死锁导致部分数据丢失?

partial data loss from deadlock?

我遇到这样一种情况,由于 DB 死锁,我们丢失了部分数据。使用相同的过程将值插入到多个表中,但数据丢失只发生在少数几个表中。这真的可能吗?

默认情况下,交易需要在 SQL 服务器中明确。因此,如果您的程序结构如下:

create procedure dbo.doStuff
as
begin
   update table1 …;
   update table2 …;
   delete table3 …;
   insert table4 …;
end

并且您在 table3 删除中遇到死锁,对表 1 和 2 的更新结果应该被认为是持久的(也就是说,它们不会被死锁的回滚所回滚)。如果您需要所有语句以原子方式 succeed/fail ,则需要将整个事物包装在一个事务中。即:

create procedure dbo.doStuff
as
begin
   begin transaction;
      update table1 …;
      update table2 …;
      delete table3 …;
      insert table4 …;
   commit transaction;
end

请记住,这确实对并发性有影响(您持有锁的时间更长)- 不是免费的。而且,虽然你不能依赖它,但它也可以影响哪个进程是死锁受害者(因为部分选择是 "how much work would it be to roll back")!

如果您愿意,您可以(并且可能应该!)使用 begin tryxact_state() 变得更高级,但以上是基础知识。