SQL隔离级别,从锁谈起

用过SQL的童鞋应该都对SQL的数据隔离级别有所了解。知其然,更应知其所以然。本文从锁的角度解析SQL数据库的隔离级别,以期能够对SQL数据隔离有更深入的理解。

首先简短的回顾一下与隔离级别相关的三种数据库读写异常:

读写异常异常描述
脏读(Dirt Read)事务读取到其它事务未提交的变更
不可重复读(Unrepeatable Read)事务两次读取的记录不一致(由Update引起)
幻读(Phantom Read)事务两次读取的记录数不一致(由InsertDelete引起)

对应于三种读写异常,SQL标准定义了4中事务隔离级别:

事务隔离级别脏读不可重复读幻读
读未提交允许允许允许
读提交不允许允许允许
可重复读不允许不允许允许
序列化不允许不允许不允许

用过Linux的pthread多线程库的童鞋应该都知道读写锁。读写锁有下述逻辑:

  • 多次上读锁,不会有线程被阻塞
  • 先上读锁后上谢谢,写线程阻塞
  • 先上写锁,后上读锁,读线程阻塞
  • 多次上写锁,写线程阻塞

SQL锁用的锁跟读写锁机器类似,也分为读锁和写锁。为了实现4中事务的隔离级别,还需要实现锁的粒度的划分。所谓粒度,即锁的作用范围,比如:表级别的作用范围,或者元组级别的作用范围。

现在可以简单的说明四种隔离级别所对应的加锁机制。

  • 序列化:操作前对表上锁(粒度到表),读写操作都加上写锁。因为任何操作都需要获取写锁,所以一旦写锁被其他事务占用,该事务将被阻塞,因此不会出现不可重复读。由于粒度到表,因此不会出现幻读。
  • 可重复读:读上读锁,写上写锁,粒度到行。读操作上读锁,实现了读取操作的并发访问;写操作上写锁,先读后写,写操作被阻塞,因此不会出现不可重复读取;先写后读,读操作将被阻塞,因此也不会造成不可重复读取;最后两个写操作自然也是阻塞。又因为锁的粒度到行,对于表级别的操作,由于不同的行被上了不同的锁,所以,会出现幻读。
  • 读提交:与可重复读类似,只不过上锁的时期是读操作瞬间,读操作结束后就解锁。能够实现了读写的并发,允许读取的数据被修改,会出现两次读操作不一致的情况。
  • 读未提交:读不加锁,实现读读、读写的并发。注意,两个写操作是不能并发的。

一张表总结:

事务隔离级别读读并发读写并发写读并发写写并发
读未提交允许允许允许不允许
读提交允许允许不允许不允许
可重复读允许不允许不允许不允许
序列化不允许不允许不允许不允许

最后,查询数据库隔离级别的语句:select @@global.tx_isolation。MySQL默认的隔离级别是可重复读

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值