更新堆 table - RID 上的死锁
UPDATE heap table - Deadlock on RID
我正在设置一个测试用例来证明某个死锁场景,并且需要对正在发生的事情有一些了解。
我有一个堆 table,通常称为 HeapTable。这个table被2个交易同步更新。
事务 1:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Dylan'
WHERE FirstName = 'Ovidiu';
WAITFOR DELAY '00:00:15';
UPDATE HeapTable
SET FirstName = 'Bob'
WHERE FirstName = 'Thierry';
ROLLBACK TRANSACTION
事务 2:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';
ROLLBACK TRAN
我首先触发事务 1,紧接着是事务 2。正如预期的那样,事务 1 将要求一些独占锁,以及一些意向独占锁。事务 2 将进入并请求同一 RID 上的更新锁:
spid dbid ObjId IndId Type Resource Mode Status
55 5 711673583 0 RID 1:24336:10 X GRANT
57 5 711673583 0 RID 1:24336:10 U WAIT
我有点惊讶地看到第二个事务要求对同一个 RID 进行更新锁定,因为我认为这指向单个记录并且两个更新语句处理不同的数据。我以某种方式期待页面级别的冲突。
当事务 1 的第二次更新启动时,事务 2 将被视为死锁牺牲品,导致事务 2 回滚并完成事务 1。
有人能解释一下为什么第二个事务需要对同一个 RID 进行更新锁定,尽管它更新了不同的记录吗?
Can someone explain me why the second transaction would require an update lock on the same RID although updating a different record?
这可以改写为,当不存在索引时,Update 语句如何获取需要更新的 table 上的锁..
SQL 在 Page 上加一个 intent Exclusive 锁,然后在读取它之前尝试在页面的行上加 U 锁,如果它与要更新的值匹配,这个锁将转换成X锁..
这个U锁策略是为了保证同一行不会有其他不兼容的锁
请参阅下文 link 作者 Kalen Delaney 以了解有关相同内容的深入详细信息
http://sqlblog.com/blogs/kalen_delaney/archive/2009/11/13/update-locks.aspx
我正在设置一个测试用例来证明某个死锁场景,并且需要对正在发生的事情有一些了解。 我有一个堆 table,通常称为 HeapTable。这个table被2个交易同步更新。
事务 1:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Dylan'
WHERE FirstName = 'Ovidiu';
WAITFOR DELAY '00:00:15';
UPDATE HeapTable
SET FirstName = 'Bob'
WHERE FirstName = 'Thierry';
ROLLBACK TRANSACTION
事务 2:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';
ROLLBACK TRAN
我首先触发事务 1,紧接着是事务 2。正如预期的那样,事务 1 将要求一些独占锁,以及一些意向独占锁。事务 2 将进入并请求同一 RID 上的更新锁:
spid dbid ObjId IndId Type Resource Mode Status
55 5 711673583 0 RID 1:24336:10 X GRANT
57 5 711673583 0 RID 1:24336:10 U WAIT
我有点惊讶地看到第二个事务要求对同一个 RID 进行更新锁定,因为我认为这指向单个记录并且两个更新语句处理不同的数据。我以某种方式期待页面级别的冲突。
当事务 1 的第二次更新启动时,事务 2 将被视为死锁牺牲品,导致事务 2 回滚并完成事务 1。
有人能解释一下为什么第二个事务需要对同一个 RID 进行更新锁定,尽管它更新了不同的记录吗?
Can someone explain me why the second transaction would require an update lock on the same RID although updating a different record?
这可以改写为,当不存在索引时,Update 语句如何获取需要更新的 table 上的锁..
SQL 在 Page 上加一个 intent Exclusive 锁,然后在读取它之前尝试在页面的行上加 U 锁,如果它与要更新的值匹配,这个锁将转换成X锁..
这个U锁策略是为了保证同一行不会有其他不兼容的锁
请参阅下文 link 作者 Kalen Delaney 以了解有关相同内容的深入详细信息
http://sqlblog.com/blogs/kalen_delaney/archive/2009/11/13/update-locks.aspx