我正在使用SSIS实现upsert操作
一般的包结构是
<Begin transaction>
<read config values>
<Data flow task>
<commit transaction>
数据流任务由
组成<oledb Source>
<Lookup>
<matched output to Update using oledbcommand>
<No Match output to Insert using oledbcommand>
当只有插入
时,包第一次正常运行在第二次运行时,当发生一组更新,然后发生插入时,Update语句最终在目标表上保持独占锁定,与AWAITING COMMAND
一起进入休眠状态,而插入被暂停并继续等待锁定。
为了检查最后一段中的陈述,我使用了以下命令:
select * from master.sys.sysprocesses where blocked<>0 or spid in (select blocked from master.sys.sysprocesses where blocked <>0)
有没有办法解决这种锁定情况?
答案 0 :(得分:4)
由于您明确控制了您的交易,您是否将RetainSameConnection
属性设置为true?否则,您将有两个+数据库连接到同一资源,并插入和更新同一个表,但在不同的事务上,这将导致您遇到的行为。
答案 1 :(得分:3)
已知OLEDB Command存在问题。它一次在一行上执行,类似于光标。所以它很慢,特别是如果你要处理大量的记录。我不能确切地说为什么有锁定,但我想这是因为其他进程试图同时访问该表。
最好将数据流任务更改为以下内容:
oledb source
查找
没有匹配输出到OLEDB目的地,直接添加目的地,这里不需要OLEDB命令来插入。
将匹配的记录转移到目标数据库中的临时表
在控制流程中,使用execute sql task和update语句来执行更新:现在执行基于set的更新。比原始配置更快。
SQL Server Central上的This article遍历实现。建议它使用2005,您需要对查找转换进行微小的更改以适应2008套件。