(NOLOCK 说白了是不加锁查询,可以读取被事务锁定的数据,也称为脏读),我们还是继续看一下用于测试事务
事务1:
A根据条件查询名字为'kk'的记录数据,然后作标记,把名字为kk的记录中info作数据更新(A变更的)
--事务1
begin tran
select * from dbo.Test_Dead(nolock) where name = 'kk'
waitfor delay '00:00:05'
update T set info = 'A更改' from Test_Dead T(nolock) where name = 'kk'
commit tran
事务2:
B根据条件查询名字为'kk'的记录数据,然后作标记,把名字为kk的记录中info作数据更新(B变更的)
--事务2
begin tran
select * from dbo.Test_Dead(nolock) where name = 'kk'
waitfor delay '00:00:05'
update T set info = 'B更改' from Test_Dead T(nolock) where name = 'kk'
commit tran
1.我们先看原有数据如下图。。。有两个记录
2.我们开始分别执行事务1和2,现有数据如图
事务1和2读取到数据都是,
因此【事务1】更改了数据,但是没有被读到。最终【事务2】的更改覆盖了【事务1】的更改值,最终结果如下图
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
【改如何解决呢?】解决:允许对事务操作加锁 READ UNCOMMITTED:即未提交的数据只能读取,不能更改
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
测试1,我们将表中数据还原至
再次执行如下图所示事务1和事务2
--事务1
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN tran
update T set info = 'A更改' from dbo.Test_Dead T WHERE name = 'kk'
waitfor delay '00:00:10'
ROLLBACK
--事务2
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
begin tran
select * from dbo.Test_Dead where name = 'kk'
--update T set info = 'B更改' from dbo.Test_Dead T WHERE name = 'kk'
commit tran
结果是:
当事务1开始执行时,执行事务2,是可以读取到事务1已经更改的结果值(但是只可以读取,不可以更改)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
测试2,如果我们把事务1和2的隔离等级设置为READ COMMITTED
结果是:
当事务1开始执行时,执行事务2,此时事务2一直阻塞直到事务1完成,才能读取到值(更改的数据只能是提交后才能读取)