一文搞定 Spring事务( 四 )

执行结果
事务线程-A【查询结果】:Book(bid=1, title=Netty, author=李老师, price=99.9)事务线程-B 执行结果:1事务线程-A【查询结果】:Book(bid=1, title=Netty, author=李老师, price=99.9)

查看执行结果可知,我们线程B执行的是更新操作,但是更新成功后,在事务A进行查询时,本应是我们更新后的数据,这才对呀 。所以这个事务出现了事务不同步的问题 。
为了保证并发状态下的数据读取的正确性,就需要通过事务的隔离级别来进行控制,实际上控制的就是脏读、幻读以及不可重复读的问题了 。
4.1、脏读
脏读(Dirty reads):事务A在读取数据时,读取到了事务B未提交的数据,由于事务B有可能被回滚,所以该数据有可能是一个无效数据

一文搞定 Spring事务

文章插图
4.2、不可重复读
不可重复读(Non-repeatable Reads):事务A对一个数据的两次读取返回了不同的数据内容,有可能在两次读取之间事务B对该数据进行了修改,一般此类操作出现在数据修改操作之中;

一文搞定 Spring事务

文章插图
4.3、幻读
幻读(Phantom Reads):事务A在进行数据两次查询时产生了不一致的结果,有可能是事务B在事务A第二次查询之前增加或删除了数据内容所造成的.

一文搞定 Spring事务

文章插图
Spring最大的优势是在于将所有的配置过程都进行了标准化的定义,于是在TransactionDefintion接口里面就提供了数据库隔离级别的定义常量 。

一文搞定 Spring事务

文章插图
从正常的设计角度来讲,在进行Spring事务控制的时候,不要轻易的去随意修改隔离级别(需要记住这几个隔离级别的概念),因为一般都使用默认的隔离级别,由数据库自己来实现的控制 。
【MySQL数据库】查看MySQL数据库之中的默认隔离级别
SHOW VARIABLES LIKE 'transaction_isolation';举个栗子,来看看隔离级别的作用吧
修改testInsertIsolation测试类
definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);// 设置事务隔离级别为:读已提交执行结果:
因为我们线程B在修改后,就提交了,而我们设置的隔离级别是读已提交,所以能读到已提交的数据
事务线程-A【查询结果】:Book(bid=1, title=Java入门到入土, author=李老师, price=99.9)事务线程-B 执行结果:1事务线程-A【查询结果】:Book(bid=1, title=Netty, author=李老师, price=99.9)5、Spring事务传播机制
事务开发是和业务层有直接联系的,在进行开发的过程之中,很难出现业务层之间不互相调用的场景,例如:存在有一个A业务处理,但是A业务在处理的时候有可能会调用B业务,那么如果此时A和B之间各自都存在有事务的机制,那么这个时候就需要进行事务有效的传播管理 。

一文搞定 Spring事务

文章插图

一文搞定 Spring事务

文章插图
1、TransactionDefinition.PROPAGATION_REQUIRED:默认事务隔离级别,子业务直接支持当前父级事务,如果当前父业务之中没有事务,则创建一个新的事务,如果当前父业务之中存在有事务,则合并为一个完整的事务 。简化的理解:不管任何的时候,只要进行了业务的调用,都需要创建出一个新的事务,这种机制是最为常用的事务传播机制的配置 。

经验总结扩展阅读