这个问题是关于并发高速插入。我必须承认这在我看来很有趣。
我使用Server 2008 R2执行T插入和插入触发器后。
我希望确保在insert和它的后插入触发器之间不会执行任何命令。
使用隔离级别会导致死锁,或者仅仅是而不是解决了问题。
我使用的过程是从菲尔到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参见ID #9和#10。切换了ItemID。ItemID应该分别是5和6,而不是6和5,但是第10次插入可能发生在#9的后插入触发器完成执行之前。
这一问题发生的不到0.5%的插入:2个开关涉及4个记录1000插入或更少。是的,有时没有开关发生。
将隔离级别提高一步是没有帮助的,甚至会导致更多的键/依赖键不时切换。提高两个隔离级别会导致死锁。
降低隔离级别可以减少开关,但它们仍然是创建的。
在每次插入之前启动提高的隔离级别,并在触发器结束时返回到默认的隔离级别会导致死锁(在我的实验中,所有插入都没有提交!)
有人找到出路了吗?
如何强制插入和它的后插入触发器一起执行,禁止其他插入到同一表之间?
发布于 2012-06-29 15:37:32
使用而不是插入触发器怎么样?
当然,您必须自己进行实际的插入,但这是Server中支持的行为。在插入前没有触发器或类似的内容。
无论如何,您仍然可以在这种类型的触发器中使用当前的触发器处理逻辑。
为了想出更好的解决方案,你能解释一下你想做什么吗?此表中是否插入多个线程?这是一个实时过程吗?
就像拍卖一样。是的,多个线程正在此表中插入。问题出在后面,但确实发生了。目前还没有理由抱怨,但可能会有(到现在为止,开关还没有发生在临界点)。启动插入的用户需要知道他们在订单列表中的优先级。ItemID的使用几乎迫在眉睫,因此,不能动态计算(选择计数(*).在哪里.)稍后,当需要一个毫秒的问题时。错误的ItemID顺序可能会给一个人造成损失,而对另一个人则会造成不正当的收益。
在SQL server中,多线程插入几乎不是一个好主意。至少在没有某种同步的情况下。
你需要排队。例如,我有一个类似的系统,每天需要插入250万到300万条记录(嗯,工作时间)。
起初,我还使用8-16个线程直接在数据库上插入。我注意到了这种行为:死锁。因此,我开始考虑如何对这些消息进行排队,以便在任何时候只插入一个线程(1个连接)。
最后,我在MSMQ (事务性)中排队处理这些记录。其他一些进程从这里(也是事务性的)开始并将它们批量插入到数据库中。我的记录一定会按正确的顺序送来,也就是寄去的那一份。
因此,这个次要过程插入了大量记录,就像您一样,我需要在插入之前进行一些预处理,而不是插入触发器。在那里,我可以“安静地”更新整个inserted表,而不必担心有人会来搅乱我的东西。
这只是个主意。您还可能想要考虑Service的排队,特别是如果您不想在Server之外进行处理的话。
另外,值得尝试的是使用快照隔离级别和行版本控制进行事务处理,但我建议采用MSMQ/Service方式。
https://stackoverflow.com/questions/11264589
复制相似问题