2

首先,我想知道 SQL Server 2005 中死锁的实际根本原因是什么。是因为当两个进程访问表中的同一行时?

无论如何,请考虑两个表_Table_Now_,并且_Table_History_两者都具有相同的结构。

假设有一列称为NAME

因此,当一个进程尝试使用 in 更新记录时NAME='BLUE'_Table_Now_首先,它需要将当前行NAME='BLUE'放入_Table_History_然后更新 _Table_Now_,并删除以前存在的行_Table_History_

删除时发生死锁。我不明白为什么?

请指导我!

4

2 回答 2

1

死锁基本上意味着当进程 A 依赖于进程 B 而进程 B 依赖于进程 A 时,所以 A 只会在 B 完成时开始\继续,而 B 只会在 A 完成时开始\继续

您可能遇到的是表(或行)锁定,因此 SQL 在更新表之前锁定该行,以确保在执行更新时没有其他进程尝试访问该行。

您能否更具体地说明您是如何进行插入\更新\删除的。在这种情况下,您不应该出现死锁。

仅供参考,不要使用with (NOLOCK). 它会阻止锁定,但它通过告诉 SQL Server 读取未提交的数据来做到这一点,并且最终可能导致数据不一致。

于 2012-05-03T10:30:54.757 回答
0

当进程 A 等待进程 B 释放资源而进程 B 等待进程 A 释放资源时,就会发生死锁。

如果我正确理解更新的顺序,它是这样的:
1. 读取 Table_Now 中的一行
2. 更新 Table_History 中的一行
3. 更新 Table_Now 中的一行
4. 删除 Table_History 中的一行。

如果您不正确地使用事务或锁定,这可能是一个有风险的命令。

为避免死锁,对于每个进程,您应该执行:
1. 开始事务(最好是表锁)
2. 执行所有数据库操作
3. 提交事务(或回滚,以防数据库更新时出现任何问题)

这将确保每个进程锁定两个表,执行所有操作然后退出。

如果您已经在使用事务,您使用的是什么范围和级别?如果没有,请引入交易。它应该可以解决问题。

于 2012-05-03T12:42:59.423 回答