1

任务:

打开更新某些行并回滚的第一个事务(T1)(总是)

在同一时间(在打开 T1 之后但在回滚之前)其他事务 T2 可以修改相同的行并提交它

在这种情况下 T2 等待 T1(使用 READ_COMMITTED_SNAPSHOT 隔离级别)

可以不等待就完成吗?

示例:第一个查询窗口

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'

4

2 回答 2

1

所有 DML 总是采用 X 锁。这样可以可靠地执行回滚。没办法,这是引擎的核心原理。

你需要一种不同的方法。无论如何都不建议使用锁做异国情调的东西,因为它很难正确且难以测试。

在不知道您要完成的工作的情况下,我无法提出更好的选择。

于 2015-05-25T09:58:18.890 回答
0

我们可以使用“with (nolock)”或“READ_COMMITTED_SNAPSHOT = false”读取一行而无需等待,但我们不能在没有独占锁的情况下更新或删除一行。

于 2015-05-25T07:13:18.677 回答