如何强制插入触发器在插入之后执行,执行任何其他插入之前?

Dif*_*222 1 sql t-sql sql-server sql-server-2008 sql-server-2008-r2

此问题与并发高速插入有关.我必须承认,在我眼中这是非常有趣的.

我正在使用SQL Server 2008 R2执行T-SQL插入和插入触发器之后.

我想确保在插入和插入后触发器之间不会执行任何命令.

使用隔离级别导致死锁或只是不解决问题.

我正在使用的程序是从Phil到SQL Server依赖身份的答案/解决方案 - 有这样的事情吗?

问题是:

有时插入介于前一个插入和插入后触发之间,导致此结果:

RoomID  ItemID  ItemDescription ID
------  ------  --------------- --
7       1       Door             1
7       2       Window (West)    2
7       3       Window (North)   3
8       1       Door             4
8       2       Table #1         5
8       3       Table #2         6
7       4       Table #1         7
8       4       Chair #1         8
7       6       Table #2         9
7       5       Table #3        10
8       5       Chair #2        11
Run Code Online (Sandbox Code Playgroud)

参见ID#9和#10.Thair ItemID被切换.ItemID应分别为5和6而不是6和5,但第10次插入可能发生在#9完成执行的后插入触发器之前.

此问题发生的插入次数少于0.5%:2个开关涉及4个记录,1000个插入或更少.是的,有时候没有开关发生.

将隔离级别提高一步并没有帮助,甚至会导致更多的键/从属键不时切换.提高两个隔离级别会导致死锁.

降低隔离级别会减少交换机,但仍会创建它们.

在每个插入之前启动提升的隔离级别并在触发器结束时移回到默认隔离级别会导致死锁(在我的实验中,所有插入都没有提交!).

有没有人看到出路?

如何强制插入及其后插入触发器一起执行,禁止其他插入到同一个表之间?

Mar*_* N. 5

如何使用而不是插入触发器

当然,您必须自己制作实际的插件,但这是SQL Server中支持的行为.之前没有插入触发器或类似的东西.

无论如何,您仍然可以在此类触发器中使用当前的触发器处理逻辑.

试图想象一个更好的解决方案,你能解释一下你想要做什么吗?是否有多个线程插入此表?这是一个实时流程吗?

像拍卖一样.是的,此表中插入了多个线程.问题是后方但发生了.没有理由抱怨,但可能存在(现在发生的转换不在关键点).启动插入的用户需要知道在订单列表中它们的优先级.ItemID几乎是即将使用的,因此,可能无法在需要的时候动态计算(选择计数(*)...其中......),需要几毫秒.ItemID的错误顺序可能导致一个损失,另一个非合理收益.

好吧,多线程插入在SQL服务器中几乎不是一个好主意.至少没有某种同步.

你需要某种排队.例如,我有一个类似的系统,需要每天插入250-3万条记录(好吧,工作时间).

起初我还使用8-16个线程直接在数据库上进行插入.我注意到了这种行为:死锁.所以我开始考虑如何排队这些消息,因此任何时候只能插入1个线程(1个连接).

我最终在MSMQ(事务性)中排队这些记录.其他一些进程来自这里(也是事务性的)并将它们分批插入数据库中.我的记录保证按照正确的顺序排列,即发送它们的顺序.

所以这个辅助进程插入了批量记录,因为在插入之前我需要一些预处理,我正在使用一个替代插入触发器.在那里,我可以inserted"安静地" 更新整个表格,而不用担心有人会来弄乱我的东西.

这只是一个想法.您可能还需要考虑Service Broker进行排队,特别是如果您不想在SQL Server外部进行处理.

此外,值得尝试的是具有快照隔离级别和行版本控制的事务,但我建议采用MSMQ/Service Broker方式.