事务:事务配置的规律-Spring MVC+ mybatis 环境

Posted 蜗蜗工作室

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事务:事务配置的规律-Spring MVC+ mybatis 环境相关的知识,希望对你有一定的参考价值。

事务隔离特性和传播特性

基于上一篇文章,我们使用 Spring MVC+mybatis+mysql 的环境,通过在 Controller 层增加多线程的方式,实验并发环境下事务的传播特性和隔离特性。

注意事项

  • 事务是数据库的特性, 需要数据库开启事务配置,而 mybatis 和 Spring 都可以“接管”具体的事务配置。

  • 对于controller 访问,实际上服务器是按照多线程模式处理的,即两次访问互不影响,但是如果使用同一个浏览器做连续访问,服务器会做出串行访问的处理,造成访问速度下降,而且,当首次访问时间超时的时候,后面的访问会被安排开始执行。所以我们采取 Controller 层增加多线程的方式,运用单例模式共享变量的方式控制多个线程之间访问的事务,以模拟多种事务并发或者传播的规律。

  • mybatis 有一级缓存默认开启,即同一个Mapper方法在一个事务里执行多次实际上只查询了一次,由于事务是锁定于数据库的数据的,我们可以通过写冗余方法来简单规避这个问题,否则不可重复读就无法出现

  • 一般的事务都是加在 Service 层,本文就直接论述为 Service层配置事务

传播特性的规律

  • 多次调用同一个Service,从传播特性来说,二者的事务相互独立,互相不影响。

  • 分开访问两个不同的Service也是相互独立的,二者的事务相互独立,互相不影响。

  • 事务的传播特性仅在Service调用Service的情况时才需要将两个 Service 合起来考虑,而且是出于调用本Service的来源是否具有事务配置的出发点来考虑的。比如已存在事务则共享,如果没有事务则报错

  • 对于 Service 来说如果存在事务,一旦程序执行失败,或者主动抛出未捕获的异常,事务都会回滚,而且,事务内所有程序要么全部执行并提交,要么全部回滚。

  • Service1调用了Service2,从传播特性上来说,Service2可以和Service1保持为同一事务,也可以新起事务,也可以不使用事务,也可以检查事务。

  • 事务1调用事务2,如果事务1配置为有事务,事务2配置为和事务1保持为同一事务,则任何一个报异常,两个Service的事务都会回滚,而且,后面的事务可以读取前面事务的未提交数据,即两个Service 之间的隔离特性失效。

隔离特性的规律

  • 一个事务内,隔离特性失效,如果两个Service使用同一个事务,隔离特性就失效了。

  • 两个事务单独访问,读未提交,允许本事务别取其他事务的未提交数据。无法避免脏读、不可重复读、幻读

  • 两个事务单独访问,读已提交,本事务只能读取其他事务已经提交的数据。可以避免脏读,无法避免不可重复读、幻读

  • 两个事务单独访问,可重复读,本事务内重复读取某一条数据结果始终不变,期间允许其他事务对该数据进行修改和删除。可以避免脏读、不可重复读,无法避免幻读

  • 两个事务单独访问,序列化,涉及到本事务操作的数据或者表,只有本事务提交后,其他事务才可以执行,反之,如果其他事务正在执行,本事务需要等待,需要强调的是,序列化并不是完全意义的串行,而是在涉及到表操作的时候串行,其他代码是并行的关系,这算是一种优化吧。序列化设置可以避免脏读、不可重复读和幻读。

对于常规事务配置的建议

  • 对于普通查询

@Transactional(readOnly=true,isolation=Isolation.READ_COMMITTED,
propagation=Propagation.SUPPORTS,rollbackFor=Exception.class)
 
   
   
 
  • 1

  • 2

  • 对于普通新增或者修改

@Transactional(readOnly=false,isolation=Isolation.READ_COMMITTED,
propagation=Propagation.REQUIRED,rollbackFor=Exception.class)


以上是关于事务:事务配置的规律-Spring MVC+ mybatis 环境的主要内容,如果未能解决你的问题,请参考以下文章

有没有高手指点一下,spring mvc 注解的方式下如何编写一个事务,对两个表同时操作

手写 Spring 事务IOCDI 和 MVC

java的框架spring如何配置分布式事务?

spring读写分离 - 事务配置篇(转)

关于Spring事务<tx:annotation-driven/>的理解(Controller可以使用@Transactional)

MySQL8-事务