交易陷入僵局
Posted
技术标签:
【中文标题】交易陷入僵局【英文标题】:Transaction was deadlocked 【发布时间】:2011-01-07 08:33:56 【问题描述】:我得到以下 sql 异常: 事务与另一个进程在锁资源上死锁,并已被选为死锁牺牲品。重新运行事务。在批处理结束时检测到不可提交的事务。事务被回滚。 我在任何存储过程中都没有任何事务,我从 .net 进行事务处理,我总是使用 using 调用它们。 你们以前遇到过这种情况吗?
【问题讨论】:
【参考方案1】:事务就是事务,无论从哪里开始。无论是在 c# 中还是在 RDBMS 中。
您的using
有效地发出BEGIN TRANSCATION。
MSDN (for SQL Server 2000 but still valid)建议你在检测到死锁时自动重试,而不是在这里写代码,谷歌上有很多结果供你细读。
【讨论】:
IMO MSDN 在这方面完全是错误的。如果您只是不加思索地自动重试,您很可能会覆盖其他人的更改,也就是丢失的更改。 @AlexKuznetsov:我发现死锁通常不会发生在同一行的同一操作,而是另一个进程的同一表/页面/索引上。如果您对一行的写入路径最少,则使用相同代码/操作的 2 个并发进程不应死锁。然而,一个 INSERT parent to child,一个 DELETE child to parent 可以很好地做到。就我而言,无论如何我都会寻找其他更改:例如,我不知道数据在屏幕上显示多长时间以进行编辑。 我不同意“使用相同代码/操作的并发进程不应死锁” - 这是一个重现,它显示了存储的 proc 如何与相同的 proc 解除锁定形成另一个连接:@987654322 @ 想一想,如果我们是死锁的受害者,可能有人修改了我们试图更新的相同数据。用同一个代码修改真的有关系吗?【参考方案2】:使用事务时需要小心,因为默认情况下它将隔离级别设置为可序列化。当连接释放回池中时,它仍将设置该级别。这会严重损害并发性。
【讨论】:
以上是关于交易陷入僵局的主要内容,如果未能解决你的问题,请参考以下文章