无写锁更新
Update without write lock
任务:
打开更新某些行并回滚(始终)的第一个事务 (T1)
在同一时间(在打开 T1 之后但在回滚之前)其他事务 T2 可以修改相同的行并提交它
在这种情况下,T2 等待 T1(使用 READ_COMMITTED_SNAPSHOT 隔离级别)
可以不用等吗?
示例:
第一次查询window
IF NOT EXISTS ( SELECT *
FROM sysobjects
WHERE name = 'TestLockTable'
AND xtype = 'U' )
BEGIN
CREATE TABLE TestLockTable
(
Id INT NOT NULL ,
Name VARCHAR(64) NOT NULL
)
END
INSERT INTO dbo.TestLockTable
( Id, Name )
VALUES ( 1, 'test' )
BEGIN TRANSACTION T1
UPDATE dbo.TestLockTable
SET Name = 'test1'
WHERE Id = 1;
第二个:
BEGIN TRANSACTION T2
SELECT *
FROM dbo.TestLockTable
WHERE Id = 1; --Select 'test' without wait
UPDATE dbo.TestLockTable
SET Name = 'test2'
WHERE Id = 1; --This T2 hang on
COMMIT TRANSACTION T2
最后一个:
ROLLBACK TRANSACTION T1
回滚 T1 后,T2 可以提交,我们在行 'test2' 中得到
我们可以使用 "with (nolock)" 或 "READ_COMMITTED_SNAPSHOT = false" 读取一行而无需等待,但我们无法在没有排他锁的情况下更新或删除一行..
所有 DML 始终采用 X 锁。这样才能可靠地执行回滚。没办法,这是引擎的核心原理。
您需要一种不同的方法。无论如何都不推荐使用锁来做奇特的事情,因为它很难正确而且很难测试。
在不知道你想要完成什么的情况下,我无法提出更好的选择。
任务:
打开更新某些行并回滚(始终)的第一个事务 (T1)
在同一时间(在打开 T1 之后但在回滚之前)其他事务 T2 可以修改相同的行并提交它
在这种情况下,T2 等待 T1(使用 READ_COMMITTED_SNAPSHOT 隔离级别)
可以不用等吗?
示例: 第一次查询window
IF NOT EXISTS ( SELECT *
FROM sysobjects
WHERE name = 'TestLockTable'
AND xtype = 'U' )
BEGIN
CREATE TABLE TestLockTable
(
Id INT NOT NULL ,
Name VARCHAR(64) NOT NULL
)
END
INSERT INTO dbo.TestLockTable
( Id, Name )
VALUES ( 1, 'test' )
BEGIN TRANSACTION T1
UPDATE dbo.TestLockTable
SET Name = 'test1'
WHERE Id = 1;
第二个:
BEGIN TRANSACTION T2
SELECT *
FROM dbo.TestLockTable
WHERE Id = 1; --Select 'test' without wait
UPDATE dbo.TestLockTable
SET Name = 'test2'
WHERE Id = 1; --This T2 hang on
COMMIT TRANSACTION T2
最后一个:
ROLLBACK TRANSACTION T1
回滚 T1 后,T2 可以提交,我们在行 'test2' 中得到
我们可以使用 "with (nolock)" 或 "READ_COMMITTED_SNAPSHOT = false" 读取一行而无需等待,但我们无法在没有排他锁的情况下更新或删除一行..
所有 DML 始终采用 X 锁。这样才能可靠地执行回滚。没办法,这是引擎的核心原理。
您需要一种不同的方法。无论如何都不推荐使用锁来做奇特的事情,因为它很难正确而且很难测试。
在不知道你想要完成什么的情况下,我无法提出更好的选择。