对大多数Java开发者来说,Spring事务管理是Spring应用中最常用的功能,使用也比较简单。本文主要逐步介绍Spring事务管理的相关知识点及原理,作为Spring事务管理的学习总结。

一、关键类

事务真正的开始、提交、回滚都是通过PlatformTransactionManager这个接口来实现的,例如,我们常用的org.springframework.jdbc.datasource.DataSourceTransactionManager。

TransactionDefinition用于获取事务的一些属性,Isolation, Propagation,Timeout,Read-only,还定义了事务隔离级别,传播属性等常量。

TransactionStatus用于设置和查询事务的状态,如是否是新事务,是否有保存点,设置和查询RollbackOnly等。

二、声明式事务

所谓声明式事务,就是通过配置的方式省去很多代码,从而让Spring来帮你管理事务。本质上就是配置一个Around方式的AOP,在执行方法之前,用TransactionInterceptor截取,然后调用PlatformTransactionManager的某个实现做一些事务开始前的事情,然后在方法执行后,调用PlatformTransactionManager的某个实现做commit或rollback. 如图:

声明式事务可以通过XML配置,也可以通过Annotation的方式来配置,还可以两种结合。平时项目中看到比较多的是两种结合的方式,在XML中配置数据源,事务管理器,然后AOP相关的通过@Transactional(该注解可以注在Class,Method上)来配置。(个人感觉,AOP相关的配置用XML配置挺繁琐的,还是注解好)例如:

三、事务属性

引用官方文档的表格

(一)、value,在有多个事务管理器存在的情况下,用于标识使用哪个事务管理器

(二)、isolation,事务的隔离级别,默认是Isolation.DEFAULT,这个DEFAULT是和具体使用的数据库相关的。关于隔离级别,可以参考MySQL事务学习总结

(三)、readOnly, 是否只读,如果配置了true,但是方法里使用了update,insert语句,会报错。对于只读的事务,配置为true有助于提高性能。

(四)、rollbackFor, noRollbackFor. Spring的声明式事务的默认行为是如果方法抛出RuntimeException或者Error,则事务会回滚,对于其他的checked类型的异常,不会回滚。如果想改变这种默认行为,可以通过这几个属性来配置。

(五)、propagation, 后面会具体讲。

四、 事务的传播机制

其他的都还好理解,后面结合例子重点介绍下PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED三种传播级别。

表结构和原始数据:

(一)、PROPAGATION_REQUIRED

执行完之后,test表的数据没有任何变化。

由于MysqlTest02中的事务传播类型是Propagation.REQUIRED,逻辑上有两个事务,但底层是共用一个物理事务的,第二个事务的抛出RuntimeExcetion导致事务回滚,对于这种传播类型,内层事务的回滚会导致外层事务回滚。所以数据库中的数据没有任何变化。

(二)、PROPAGATION_REQUIRES_NEW

同样的代码,唯一的区别就是第二个事务的传播属性改成了REQUIRES_NEW,执行结果是啥?不好意思,第二个事务执行不了。

对于REQUIRES_NEW,逻辑上有两个事务,底层物理上也有两个事务,由于第一个事务和第二个事务更新的是同一条记录,对于Mysql默认的隔离级别REPEATABLE-READ来说,第一个事务会对该记录加排他锁,所以第二个事务就一直卡住了。

OK,我们把第二个事务的执行的SQL语句换成。

执行结果如下,可以看到只有第二个事务回滚了。

(三)、PROPAGATION_NESTED

对于这种传播类型,物理上只有一个事务,不过可以有多个savePoint用来回滚。当然是用这种传播类型,需要数据库支持savePoint,使用jdbc的也是要3.0版本以上(这个不太确定)。

执行结果是如下,可以看到第一个事务和第三个事务提交成功了,第二个事务回滚了。物理上它们是在一个事务里的,只不过用到了保存点的技术。

五、其他

在写测试代码的时候遇到了一个关于AOP的问题,可以看到我的测试代码,每个事务都是在一个新的class中写的。为什么不像下面这样写呢?

这是因为在Spring的AOP中,test01调用test02, test02是不会被AOP截获的,所以也不会被Spring进行事务管理。原因是Spring AOP的实现本质是通过动态代理的方式去执行真正的方法,然后在代理类里面做一些额外的事情。当通过别的类调用MysqlTest01中的test01方法时,因为使用了Spring的DI,注入的其实是一个MysqlTest01的一个代理类,而通过内部方法调用test02时,则不是。

6. Reference

Spring Framework Reference Documentation

【粉丝福利】:

《架构师资料》领取方法

关注+转发,然后私信关键词 【架构】,即可获取。

=

springaop事务逻辑原理_架构师:一篇文章掌握——Spring 事务管理相关推荐

  1. springaop事务逻辑原理_太狠了!阿里大牛手写的Spring核心面试笔记:IOC+AOP+MVC+事务...

    Spring作为现在最流行的java 开发技术,其内部源码设计非常优秀.如果你不会Spring,那么很可能面试官会让你回家等通知. Spring是什么? 有一个工地,几百号人在用铁锹铲子挖坑. 如果开 ...

  2. springaop事务逻辑原理_搞懂Spring AOP,这一篇就够了

    看了这篇文章,如果你还是不会用AOP来写程序,请你打我!! =.=||| 引言 Spring AOP是一个对AOP原理的一种实现方式,另外还有其他的AOP实现如AspectJ等. AOP意为面向切面编 ...

  3. 微服务架构 接口交互问题_架构师的故事:设计微服务架构

    架构师在软件项目中的作用是提供待解决问题的工作模型.架构师的工作是提供脚手架,开发人员将根据这些脚手架构建他们的代码,使应用程序所有部件都组合在一起. 在构建微服务架构时,项目的架构师主要关注以下3个 ...

  4. 架构师的英文缩写_架构师必备的20个英文缩写!看你知道几个?

    作为一个架构师,如果在面试的时候,面试官说出了一个英文缩写,这个时候如果你没有听过,是不是很尴尬?而且你也没办法针对这个问题进行描述回答!所以,多学习一些基础的英文缩写,一是面试可以游刃有余,二是可以 ...

  5. python架构师是做什么的_架构师成长之路(1)--什么是架构师

    前言: 哲学家常思考的问题:" 我是谁?"" 我从哪里来?"" 要到哪里去?不只是哲学家,我想每个人都有自己对这三个问题的认知. 如果我们要成为架构师 ...

  6. 解决方案架构师我需要懂代码吗_架构师真正要学会的事情

    本文引自周爱民老师[就职于南潮(Ruff),现任架构师一职]写给<程序员必读之软件架构>一书的推荐序. 编者按:软件架构师是在一个软件项目开发过程中,将客户的需求转换为规范的开发计划及文本 ...

  7. JVM优化原理—Java架构师必须要知晓的知识

    想要成为一名出色的Java架构师,必须要彻底了解Java的一个重要的特点那就JVM                                                           ...

  8. 线程同步有几种方法_架构师面试必问的多线程状态切换及常用方法

    架构师面试必问的多线程状态切换及常用方法 一.问题背景 Java架构师面试中,多线程状态切换及常用方法几乎是必问的,要掌握创建多线程的方式和方法. 二.创建多线程的几种方式 2.1方式一继承Threa ...

  9. java缓存技术redis原理_Java架构师-5分钟带你深入理解Redis的持久化方式及其原理...

    Redis 提供了两种持久化方式,一种是基于快照形式的 RDB,另一种是基于日志形式的 AOF,每种方式都有自己的优缺点,本文将介绍 Redis 这两种持久化方式,希望阅读本文后你对 Redis 的这 ...

最新文章

  1. [转]单点登录原理与简单实现
  2. 用C语言解“分段计算居民水费”题
  3. NLP千亿预训练模型的“第四范式”之Prompt Learning介绍分享
  4. 非常精美的全能视频转换器 注册版
  5. oracle数据转成sqlserver,oracle数据库转换到Sqlserver的几点经验
  6. 脚本配置文件(通过一个案例解释下什么叫脚本配置文件)
  7. 蓝桥杯 试题 基础练习 十六进制转十进制——5行代码AC
  8. 《企业私有云建设指南》-导读
  9. vb上传文件到MySQL_ASP.NET上传文件到数据库VB版
  10. 阿里云服务器ECS挑选什么样的网站环境
  11. jQuery的hide() 、show() 、toggle()
  12. Python 取dataframe某一列为特定值
  13. Spoon工具使用(kettle进行实时同步数据)
  14. 钢构cad3.5免费版及命令索
  15. 计算机省vb二级试题,湖南省计算机二级考试VB试题
  16. 基于VC++的WEB浏览器的实现
  17. 洛谷p1069 细胞分裂(noip2009普及组第三题,素数判断+筛法)
  18. 用【花生壳】穿透内网主机运用dai搭建校园实现访问外网访问只有学校内网的教务系统
  19. 举个栗子~Tableau 技巧(225):制作事件节点时间轴
  20. 怎样给电脑文件夹批量快速重新命名?

热门文章

  1. java scanner怎么用_Java Scanner delimiter()用法及代码示例
  2. 入栈和出栈c语言源程序,用c语言可执行文件实现顺序栈的出栈、入栈、判栈空、判栈满!急求啊? 爱问知识人...
  3. 怎么看电脑电源多少w_电脑电源怎么测试通电
  4. kettle kafka mysql_kettle使用kafka组件消费数据,保存到资源库无法打开问题
  5. maven项目中如何直接访问某一个页面_整一个自己的docker镜像
  6. python中的apply(),applymap(),map() 的用法和区别
  7. Python正则表达式的7个使用典范
  8. python中Dict与OrderedDict
  9. opencv python cv2.imdecode()函数报错 :TypeError: Expected cv::UMat for argument 'buf'
  10. 初学__Python——Python中文支持、Python计算器