我们看下下面的SQL语句A:
BEGIN TRANSACTION SET TRAN ISOLATION LEVEL READ COMMITTED SELECT * FROM dbo.table1 WHERE id=1 WAITFOR DELAY '00:00:12' UPDATE dbo.table1 SET A='152' WHERE Id=1 WAITFOR DELAY '00:00:12' UPDATE dbo.table1 SET A='552' WHERE Id=1 COMMIT TRAN
SQL语句B:
BEGIN DISTRIBUTED TRANSACTION SET TRAN ISOLATION LEVEL READ COMMITTED SELECT * FROM dbo.table1 WHERE id=1 UPDATE dbo.table1 SET A='222' WHERE Id=1 COMMIT TRAN
实际测试发现,当执行A时,因为A里加了时间等待,在等待期间(A还未执行到update语句时),此时去执行SQL语句B时,可以成功执行,当然它们操作的都是同一条数据,这就说明了事务在进行处理时,select是不加锁的,只有当运行到了update时才会对该条记录进行排他锁,此时无法读取,当12秒过去,再执行B,就已经变成了等待状态,因为此时该条id=1的记录已经加锁了,必须等待A的事务执行完成后才释放。
如果我们想在A中select时不允许其他事务读取的话,代码可以这样写:
SELECT * FROM dbo.table1 WITH(UPDLOCK) WHERE id=1 --将select语句加个锁
如此一来,执行A后立即执行B 此时B会等待A执行完成之后才能继续自己的事务逻辑