如何处理SSIS包中变量的共享读取锁问题?
解决SSIS包因变量锁冲突导致的冻结问题
我之前也踩过一模一样的SSIS死锁坑,看到你日志里的Lock shared read on 'User::vRequestId' failed. Error 0x80070102,瞬间懂你有多崩溃!
问题根源
这个冻结本质是变量锁冲突:ForEach循环容器在迭代时,会对正在使用的User::vRequestId加上共享读锁;当循环内触发错误、执行事件处理程序时,事件处理程序又试图读取同一个变量,两边都在等对方释放锁,直接就死锁卡住了。
具体解决步骤
核心思路就是给变量做个副本,让事件处理程序用副本而非原变量,操作起来很简单:
- 第一步:在SSIS包的变量面板里新建一个同类型的变量,比如叫
User::vRequestId_Copy(名字随便取,只要能区分原变量就行) - 第二步:在ForEach循环容器的前置环节(比如循环内的第一个任务,或者循环容器的
PreExecute事件里),把User::vRequestId的值复制到vRequestId_Copy里:- 最简单的方式是用表达式任务,设置表达式为
@[User::vRequestId_Copy] = @[User::vRequestId] - 或者用脚本任务,在C#/VB代码里写
Dts.Variables["User::vRequestId_Copy"].Value = Dts.Variables["User::vRequestId"].Value;,记得在脚本任务的变量列表里勾选这两个变量的读写权限
- 最简单的方式是用表达式任务,设置表达式为
- 第三步:把错误事件处理程序里所有用到
User::vRequestId的地方,全部替换成User::vRequestId_Copy
这样一来,事件处理程序访问的是副本变量,完全不会和ForEach循环持有的原变量锁冲突,自然就不会冻结了。
额外小提示
如果你的vRequestId是在循环迭代过程中动态更新的,一定要确保每次迭代前都重新复制一次值,保证副本和原变量的同步。
内容的提问来源于stack exchange,提问作者Abolfazl
相关产品推荐
相关产品推荐

