This answer引用this Technet article,解释了丢失更新的两种解释:
可以通过两种方式之一来解释丢失的更新。在第一种情况下,在第一个事务提交或回滚之前,当一个事务更新的 数据被另一个事务覆盖时,认为丢失更新 < / strong>即可。 SQL Server 2005中不会发生此类丢失更新,因为在任何事务隔离级别下都不允许这样做。
丢失更新的另一种解释是 一个事务(事务#1)将数据读入其本地内存 ,然后另一个事务(事务#2)更改这些数据并承诺改变。在此之后,Transaction#1根据在执行Transaction#2之前读入内存的内容更新相同的数据。在这种情况下,可以将Transaction#2执行的更新视为丢失更新。
所以看起来不同的是,在第一个场景中,整个更新发生在“本地内存”之外,而在第二个场景中则使用了“本地内存”,这就产生了不同。
假设我有以下代码:
UPDATE MagicTable SET MagicColumn = MagicColumn + 10 WHERE SomeCondition
这是否涉及“本地记忆”?是否容易对丢失的更新进行第一次或第二次解释?
答案 0 :(得分:3)
我想它会受到第二种解释。
但是,在SQL Server中实现此类UPDATE
的方式仍然无法进行丢失更新。读取更新的行受U
锁保护(实际更新行时转换为X
锁。)
U
锁与其他U
锁(或X
锁)不兼容
所以在所有隔离级别,如果两个并发事务要运行此语句,那么其中一个将最终在另一个事务的U
锁定或X
锁定后被阻止,直到该交易完成。
因此,在任何隔离级别的SQL Server中,此模式都不可能发生丢失更新。
要实现丢失的更新,您需要执行类似
的操作BEGIN TRAN
DECLARE @MagicColumn INT;
/*Two concurrent transactions can both read the same pre-update value*/
SELECT @MagicColumn = MagicColumn FROM MagicTable WHERE SomeCondition
UPDATE MagicTable SET MagicColumn = @MagicColumn + 10 WHERE SomeCondition
COMMIT