我有一个只有两个更新语句的过程。两者都在同一个表上,根据不同的列更新数据。例如
update table1
set column1 = somevalue, column2 = somevalue
where column3 = somevalue
update table1
set column3 = somevalue, column2 = somevalue
where column1 = somevalue
间歇性地收到错误
事务(进程ID“不同的数字))在锁定通信缓冲区资源上与另一个进程死锁,并被选为死锁牺牲品
当我使用命令sp_who
签入SQL Server时,进程ID指向同一存储过程。
可能存在两个update语句都可以更新同一行的情况。这可能是死锁的原因吗?
CREATE PROCEDURE update_tib_details
(@tib_id INT, @sys_id INT)
AS
BEGIN
UPDATE tib_sys_asc
SET tib_id = @tib_id
WHERE sys_id = @sys_id
UPDATE tib_sys_asc
SET sys_id = @sys_id
WHERE tib_id = @tib_id
END
答案 0 :(得分:1)
如果更新在同一进程中执行,则不会发生这种情况。单个进程不会导致自身死锁。
如果此更新被某些其他进程触发,并且不以某种方式受到并发保护,则可能会遇到死锁。
当两个进程都处于事务中间并且在另一个进程可以继续之前等待另一个进程完成时,就会发生死锁。在这种情况下,例如
Process A starts, and updates row 1
Process B starts, and updates row 2
Process A now wants to update row 2, and must wait for Process B to commit
Process B now wants to update row 1, and must wait for Process A to commit
数据库引擎非常擅长检测这些交叉依赖关系,并选择要杀死的进程。如果Process B
被杀死,Process A
最终可以更新第2行并提交,反之亦然。
在您的情况下,您应该决定适当的最终结果。如果您不关心操作完成的顺序(最后获胜),则只需在每次更新后提交。如果你关心,那么你应该能够围绕整个操作写一个独占锁(即Process B
等待,直到整个Process A
完成)。