• 深入浅出事务之隔离级别


    深入浅出事务之隔离级别

    文章分类:Java编程

    除了事务传播属性(可参考我的另一篇文章《深入浅出事务之传播属性》)之外,另一个需要开发人员关注的是事务的隔离级别,它决定了一个事务中所进行的更新操作对其它事务的可见性。事实上,DBMS、EJB、Spring都允许你设置不同的隔离级别,你必须保证它们相互统一、兼容;因此,应用服务器可能支持许多种隔离级别,但要使用其中的某一种,首先你必须保证你的数据库也支持它。

    事务的隔离性实质上是数据库的并发性与一致性的函数。随着事务隔离级别的上升,数据库的一致性随之上升,而并发性反而下降。事务隔离的这种特性实际上会影响一个应用的性能和数据完整性,例如,对于性能要求较高的应用比如信用卡处理等,您可以适当降低其事务隔离级别,以提高整个应用的并发性(但是会降低数据的完整性);对于并发量较小的应用比如财务处理等,您可以适当提高其事务隔离级别,以提高数据的完整性(但是会降低应用的性能)。大多数应用服务器和数据库都有自己默认的事务隔离级别,当然,通过Spring或EJB您可以很方便地修改。

    Spring和EJB都支持四种基本的事务隔离级别,它们是(隔离级别从低到高的顺序):
    • 读未提交(TransactionReadUncommited)
    • 读已提交(TransactionReadCommited)
    • 可重复读(TransactionRepeatableRead)
    • 串行化(TransactionSerializable)


    6.2.1、读未提交
    这是Spring所支持的最低的隔离级别,在该隔离级别下,事务允许在其它事务提交之前,读取其未提交的、对数据库的任何修改。为了说明这个问题,我们还是以在线交易为例,假设当前的价格为90.00,此时,有两个事务同时到达,事务A执行更新操作,而事务B执行查询操作;在事务隔离级别设置为“读未提交”时,该场景的处理流程如下图所示:

    ]

    注意,在t2时刻,事务A对数据库进行了一次更新操作,而它提交之前,事务B就可以在t3时刻观察到这种变化,读取到更新后的价格(94.23);也就是说,事务A中的更新操作完全没有被隔离。如果事务A因为异常回滚,那么事务B中读取的数据就是脏数据。这一隔离级别违反了最基本的ACID特性,因此很多数据库都不支持(包括Oracle) 。

    6.2.2、读已提交
    这一隔离级别允许多个事务同时操作一组数据,但是隐藏了事务之间所有未提交的更新;即事务A看不见事务B中对数据库所作的修改,直到事务B提交为止。仍然以上面的在线交易为例,此时的处理流程如下图所示:



    注意,当事务A在t2时刻更新了价格(94.23)之后,事务B在t3时刻仍然看不到该更新,此时读取价格仍然是90.00。这是一种是用较多的隔离级别,它既允许了事务B获取数据(支持并发性),同时又隐藏了其它事务(事务A)对该数据的更新,直到(事务A)提交的那一刻为止。几乎所有的数据库都支持“读已提交”的隔离级别,并且大部分将其作为缺省的隔离级别。

    6.2.3、可重复读
    这是较之前两者更为严格的事务隔离级别,它真正将所有事物相互隔离起来。该隔离级别确保,事务开始时读取到的一组数据,在整个事务周期内都不会改变(除非拥有读写锁的事务本身修改了它),直到该事务提交为止。仍然以上面的在线交易为例,此时的处理流程如下图所示:



    注意在这个例子中,尽管在事务B执行期间,事务A插入了一条数据(QRS),但是在事务B在t2时刻查询所得的结果依然和t0时刻一样(不包含QRS),即使到了t4时刻,事务A已经提交了也是如此(这一点不同于“读已提交”) 。只有在事务B也提交了,它才会看见事务A对数据库所作的修改。值得注意的是,该隔离级别下,会在被查询或修改的数据上加上读写锁,因此任何想要修改该数据的其它事务会等待(或失败),直到“可重复读”的事务提交为止。

    6.2.4、串行化
    这是JAVA所支持的最高隔离级别。在该隔离级别下,所有同时到达的事务将会“排队进入”,保证每次只允许一个事务操作数据。(我们后面将会看到,对于Oracle来说,这并不完全正确) 。使用“串行化”的隔离级别,应用的并发性明显下降,而数据完整性则显著提高。仍然以上面的在线交易为例,此时的处理流程如下图所示:



    此时,事务B将会一直挂起,直到事务A提交(或回滚) 。尽管所有的数据库都支持这种隔离级别,Oracle的处理方式略有不同,它使用“多版本数据“的方式来避免事务B的挂起。但是,如果事务B试图获取事务A所处理的数据时,Oracle会抛出ORA08177的错误信息,提示该事务隔离级别下,无法串行获取数据。
    • 大小: 25.2 KB
    • 大小: 26.2 KB
    • 大小: 26.1 KB
    • 大小: 24.7 KB
  • 相关阅读:
    Python 自动化测试实战训练营,由浅入深,从小白到测试高手!
    接口测试 Mock 实战(二) | 结合 jq 完成批量化的手工 Mock
    从文科生转行测试,再到大厂测试开发工程师,我是如何做到的?
    严正声明|严厉打击盗版侵权、非法销售「霍格沃兹测试学院」课程的违法行为
    「金羽毛」有奖征文 | 记录测试开发技术进阶之路的点滴
    测试工程师职业发展漫谈
    Workshop 深圳站|实战+源码架构剖析带你揭开Appium的神秘面纱
    那些难改的 Bug,最后都怎样了?
    BAT大厂都在用的Docker。学会这三招,面试、工作轻松hold住
    2021 开年学习送福利,助力测试进阶提升!
  • 原文地址:https://www.cnblogs.com/xiayong123/p/3717306.html
Copyright © 2020-2023  润新知