美文网首页
Spring 声明式事务(一)——隔离属性

Spring 声明式事务(一)——隔离属性

作者: 莫那一鲁道 | 来源:发表于2018-05-14 02:02 被阅读157次

    前言

    众所周知,Spring 的事务属性众多,楼主今天将对 Spring 最常用的事务 —— 声明式事务,进行彻底的解释,包括楼主也写了很多的测试例子。代码地址: 使用 tk-mybatis 的 demo 测试了 Spring 的事务

    东西很多,楼主分为 3 个部分来写,第一就是隔离属性了,第二是传播属性,第三是其他属性。

    隔离属性

    事务要解决的是多线程并发修改数据库的问题。Mysql innodb 引擎支持事务。类似 Java 中的各种锁,例如乐观锁(CAS),读写锁,悲观锁。事务也有很多级别。

    每个隔离级别要解决的问题都是不同的。

    一张表格来看看。

    以上是 Spring 事务每个隔离级别能够解决的问题。

    再说说脏读,不可重复读,幻读的解释。

    脏读场景:
    1.事务 A 读取数据
    2.事务 B 修改数据(未提交)
    3.事务 A 读取数据已和第一次读的不同

    不可重复读场景:
    1.事务 A 读取数据
    2.事务 B 修改数据(提交)
    3.事务 A 读取数据已和第一次不同

    幻读场景:
    1.事务 A 读取数据
    2.事务 B 新增数据
    3.事务 A 再次读取数据已和第一次不同

    再解释一下 4 个隔离级别:

    1. 未提交读:表示另一个事务修改了数据,还没有提交,这个事务就可以读到了。
    2. 已提交读:表示另一个事务修改了数据,同时提交了,这个事务就可以读到了,如果没提交,就读不到。
    3. 可重复读:表示另一个事务即使修改了数据(已提交),这个事务也是看不到的,因此这个事务每次读到的数据都是一样的。这叫可重复读。
    4. 可串行化:可以想象成 Java 语言的锁。一个个执行。毫无并发性。性能令人发指。

    其中关于可重复读需要解释一下在 mysql 场景下的幻读问题,按照标准,可重复读应该会导致幻读,但 mysql 如果在一个事务中,第二次读取的数据使用的是第一次的结果,因此不会产生幻读。

    关于默认的级别,很多文章说是 “已提交读”,但经过详细的测试,应该是可重复读。

    因此,大部分时候,使用默认的级别,就能得到和串行化相同的目的。而串行的成本则是非常的高昂,类似悲观锁。还有一点,mysql 的事务是借助行锁来实现的。

    相关文章

      网友评论

          本文标题:Spring 声明式事务(一)——隔离属性

          本文链接:https://www.haomeiwen.com/subject/mdordftx.html