导航
导航
文章目录
  1. 事务的特性
  2. 隔离级别的作用
  3. 问题
  4. 解决
  5. 总结
  6. 拓展

数据库事务隔离级别

事务的特性

事务具备四大特性,ACID:
1、Atomicity,原子性,事务中的操作要么全部成功,要么全部回滚失败
2、Consistency,一致性,事务执行前后,系统必须从一个一致性的状态转换到另一个,保证数据的完整性和业务状态的一致性,例如转账前后总余额不变
3、Isolation,隔离性,隔离并行事务,事务的运行不会被另一个事务干扰
4、Durability,持久性,事务一旦提交,对数据库所做的改变会被永久保存,不会被回滚,不会因断电等故障丢失

隔离级别的作用

保证数据库并发操作时,数据的正确性,保证隔离性

问题

当对数据库进行并发操作时,有可能发生以下几种问题:
1、丢失更新
两个事务同时更新一行数据,一个事务的操作覆盖了另一个的
2、脏读
一个事务读取到了另一个事务未提交的数据操作结果。这是相当危险的,因为很可能所有的操作都被回滚。
3、不可重复读
对于数据库中的某个数据,一个事务范围内,多次查询却返回了不同的数据值
这是由于在查询间隔,被另一个事务修改并提交了
脏读是读取了另一个事务未提交的脏数据,而不可重复读是读取了另一个事务提交前后的数据
4、幻读/虚读
对于数据库中的某批数据,事务的多次操作得到了不同结果,像出现了幻觉一样
原因为另一个事务做了操作:
增,多了之前未出现的数据记录
删,少了数据记录
改,多了不该有的记录,或少了该有的记录

解决

标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同
1、未授权读取/读未提交,Read Uncommitted
定义:如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据
隔离:允许脏读取,但不允许更新丢失
实现:该隔离级别可以通过“排他写锁”实现

2、授权读取/读提交,Read Committed
定义:读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行
隔离:允许不可重复读取,但不允许脏读取。
实现:这可以通过“瞬间共享读锁”和“排他写锁”实现

3、可重复读取,Repeatable Read
定义:读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务
隔离:禁止不可重复读取和脏读取,但是有时可能出现幻读数据
实现:这可以通过“共享读锁”和“排他写锁”实现

4、序列化,Serializable
定义:提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行
实现:仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到

总结

隔离级别 丢失更新 脏读 不可重复读 幻读
未提交读 Y Y Y Y
已提交读 Y N Y Y
可重复读 N N N Y
可串行读 N N N N

(Y表示可能发生,N表示不会发生)

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

拓展

Spring的五个事务隔离级别,和七个事务传播行为
http://blog.csdn.net/it_man/article/details/5074371
http://www.cnblogs.com/shitianzeng/articles/2319090.html
http://www.2cto.com/kf/201312/264064.html
http://blog.csdn.net/it_wangxiangpan/article/details/24180085
http://blog.csdn.net/edward0830ly/article/details/7569954

参考:
http://www.cnblogs.com/fjdingsd/p/5273008.html
http://baike.baidu.com/item/%E4%BA%8B%E5%8A%A1/5945882
http://baike.baidu.com/item/%E4%BA%8B%E5%8A%A1%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB
http://blog.csdn.net/shuaihj/article/details/14163713