SqlServer中的事务隔离级别、锁机制

事务

  作用:用来执行一连串的动作,并且保证所有动作要么都执行、要么都不执行。

  属性:原子行、一致性、隔离性、持久性

 

  作用:SqlServer使用锁来实施事务隔离属性。

 

阻塞

  定义:如果一个事务持有一数据资源的锁,而另一事务请求相同资源的不兼容的锁,则新锁的请求将被阻塞。

     默认情况下,被阻塞的请求会一直等待,直到原来的事务释放相关的锁。

 

事务的隔离级别

  可设置的有6个(从上往下 隔离级别越来越高):

          1、read uncommitted

          2、read committed

          3、repeatable read

          4、serializable

          5、snapshot

          6、read committed snapshot

  其中前面四个级别最常用

 

 

1、read uncommitted 脏读

例如A某正在执行如下语句:

begin tran

insert tbUnRead 

select 3,张三

union

select 4,李四

---延迟秒,模拟真实交易情形,用于处理业务逻辑

waitfor delay 00:00:05

rollback tran

此时,在等待的5秒内,B某恰好对该资源做了修改:

set Transaction isolation level read uncommitted

--查询数据

select * from tbUnRead where name like 张%

本来A某要插入两条数据,但是最后事务回滚了,此时数据库应该不存在这两条数据,但是B某却读取到了,这就是脏读。

要解决这个问题,就需要将事务隔离级别提升到read committed

 

2、read committed  不可重复读(避免脏读的最低级别)

假如A某正在执行如下操作:

set Transaction isolation level read committed

begin tran

select * from tbUnRead  where ID=2 

---延迟秒,模拟真实交易情形,用于处理业务逻辑

waitfor delay 00:00:05

select * from tbUnRead  where ID=2

此时,在等待的5秒内,B某恰好对该资源做了修改:

update tbUnRead

set name=Jack_upd

where ID=2

这样产生的结果是,在同一个事务内,两次条件相同的查询会有不同的结果。

要解决这个问题,就需要将事务隔离级别提升到repeatable read

 

3、repeatable read 幻读

假如A某在执行如下操作:

set Transaction isolation level REPEATABLE READ

begin tran

select * from tbUnRead  where ID=3 

---延迟秒,模拟真实交易情形,用于处理业务逻辑

waitfor delay 00:00:05

select * from tbUnRead  where ID=3 

commit tran

此时,在等待的5秒内,B某恰好对该资源做了修改:

INSERT tbUnRead
select 3,幻读

此时,A某已经把隔离级别设置为“可重复读”,虽然是曾经读取的数据,不管是共享锁还是互斥锁都 保留到了事务结束,但是无法阻止其他人运行新增操作,导致第一次查询时没有数据,第二次查询时却有了数据,这种现象被称为幻读。

要解决这个问题,就需要将事务隔离级别提升到serializable

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。