学习
实践
活动
专区
工具
TVP
写文章

(二)事务:事务配置的规律-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使用同一个事务,隔离特性就失效了。

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

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

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

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

对于常规事务配置的建议

对于普通查询

1

2

对于普通新增或者修改

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180225G0H48800?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

关注

腾讯云开发者公众号
10元无门槛代金券
洞察腾讯核心技术
剖析业界实践案例
腾讯云开发者公众号二维码

扫码关注腾讯云开发者

领取腾讯云代金券