1

我正在使用 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,而 Insert 被挂起并继续等待锁.

为了检查最后一段中的语句,我使用了以下命令:

select * from master.sys.sysprocesses where blocked<>0 or spid in (select blocked from master.sys.sysprocesses where blocked <>0)

有没有办法解决这种锁定情况?

4

2 回答 2

4

由于您明确控制您的交易,您是否将该RetainSameConnection属性设置为 true?否则,您将有两个以上的数据库连接到同一个资源,并在不同的事务上插入和更新同一个表,这将导致您遇到的行为。

于 2013-02-05T15:53:36.580 回答
3

已知 OLEDB 命令存在问题。它一次在一行上执行,类似于游标。所以它很慢,特别是如果你有大量的记录要处理。我不能确切地说为什么会有锁定,但我想这是因为其他进程试图同时访问表。

最好将您的数据流任务更改为以下内容:

oledb 源码

抬头

没有匹配输出到 OLEDB 目的地,直接添加目的地,这里不需要 OLEDB 命令来进行插入。

将匹配的记录转移到目标数据库中的临时表

在控制流中,使用执行 sql 任务和更新语句来执行更新:现在执行基于集合的更新。比原来的配置更快。

SQL Server Central 上的这篇文章介绍了实现。请注意,它使用的是 2005,您需要对套件 2008 的查找转换进行细微更改。

于 2013-02-05T15:44:57.293 回答