今天,尝试着写写我的第一篇文章。
想要写一篇文章可真的难啊,好多次提笔却不知到如何下笔。
最近,一直在研究Spring事务相关内容。
先抛出几个工作中常遇到的问题吧。
对于Java开发来说,应用Spring框架应该是一个程序员最基本的操作了,因此对于Spring中的事务,也一定是司空见惯了,而且用的最多的便是Spring声明式事务。但是Spring声明式事务封装的实在是太好了,以至于一个事务注解就可以完成所有的操作,因此在开发过程中,最容易被开发人员忽略,并且使用时并没有一个统一的规范。
1、事务回滚机制使用有误,导致事务失效
eg:抛出的异常与rollbackFor中异常不一致
2、事务传播机制使用有误,导致事务失效
eg:声明式事务传播机制概念混淆
3、部分写操作业务方法漏掉事务
eg:代码不够规范,review不到位
@Transaction 看似简单易用,但如果对他不了解的话,还是容易踩很多坑的。
带着这几个问题,让我们从声明式事务源头开始分析。
1、什么是事务
这是一个老生常谈的问题。事务就是一组操作,要么都执行,要么都不执行。
参考银行转账栗子。
2、事务特性
ACID
A:原子性
C:一致性
I:隔离性
D:持久性
3、事务隔离级别
读未提交
读已提交
可重复读
串行化
并发产生的问题:
脏读
不可重复读
幻读
4、Spring对事务支持
编程式事务
通过TransactionTemplate或者TransactionManager手动管理事务
声明式事务
@Transaction注解进行事务管理,无代码入侵性。(官方推荐)
5、源码分析
涉及相关类:
今天,尝试着写写我的第一篇文章。
想要写一篇文章可真的难啊,好多次提笔却不知到如何下笔。
最近,一直在研究Spring事务相关内容。
先抛出几个工作中常遇到的问题吧。
对于Java开发来说,应用Spring框架应该是一个程序员最基本的操作了,因此对于Spring中的事务,也一定是司空见惯了,而且用的最多的便是Spring声明式事务。但是Spring声明式事务封装的实在是太好了,以至于一个事务注解就可以完成所有的操作,因此在开发过程中,最容易被开发人员忽略,并且使用时并没有一个统一的规范。
1、事务回滚机制使用有误,导致事务失效
eg:抛出的异常与rollbackFor中异常不一致
2、事务传播机制使用有误,导致事务失效
eg:声明式事务传播机制概念混淆
3、部分写操作业务方法漏掉事务
eg:代码不够规范,review不到位
@Transaction 看似简单易用,但如果对他不了解的话,还是容易踩很多坑的。
带着这几个问题,让我们从声明式事务源头开始分析。
1、什么是事务
这是一个老生常谈的问题。事务就是一组操作,要么都执行,要么都不执行。
参考银行转账栗子。
2、事务特性
ACID
A:原子性
C:一致性
I:隔离性
D:持久性
3、事务隔离级别
读未提交
读已提交
可重复读
串行化
并发产生的问题:
脏读
不可重复读
幻读
4、Spring对事务支持
编程式事务
通过TransactionTemplate或者TransactionManager手动管理事务
声明式事务
@Transaction注解进行事务管理,无代码入侵性。(官方推荐)
5、源码分析
涉及相关类:
Spring框架中,事务管理相关的3个主要接口如下:
- PlatformTransactionManager: (平台)事务管理器,Spring 事务策略的核心。
- TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。
- TransactionStatus: 事务运行状态。
我们可以把 PlatformTransactionManager 接口可以被看作是事务上层的管理者,而 TransactionDefinition 和 TransactionStatus 这两个接口可以看作是事物的描述。
PlatformTransactionManager 会根据 TransactionDefinition 的定义比如事务超时时间、隔离级别、传播行为等来进行事务管理 ,而 TransactionStatus 接口则提供了一些方法来获取事务相应的状态比如是否新事务、是否可以回滚以及事务提交操作等等。
整个事务流程也可以理解为:
getTransaction 获得事务
// 执行业务代码
commit 提交事务
// 捕获异常进行回滚事务操作
rollback 回滚事务
参考该方法
org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction,由此方法便可见是以上的执行流程。
TransactionDefinition事务属性则包括了以下几种:
传播行为
隔离级别
超时设置
是否只读
TransactionStatus事务状态参考其子抽象类:
是否新事务
是否回滚
是否已完成
Spring事务断点阅读流程:
详见org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction方法。
1、获取对应事务属性TransactionAttribute
org.springframework.transaction.interceptor.TransactionAspectSupport#getTransactionAttributeSource
TransactionAttribute中便有是否是public修饰方法校验
2、获取对应事务管理器TransactionManager
org.springframework.transaction.interceptor.TransactionAspectSupport#determineTransactionManager
3、构建事务相关信息,获取事务TransactionInfo
org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary
4、通过环绕通知切面执行业务流程
5、执行成功,提交事务
org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing
6、执行失败,捕获异常,回滚事务
org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing
回滚事务时会有rollbackFor异常类型校验,判断是否需要回滚,若无,则继续提交事务:org.springframework.transaction.interceptor.TransactionAttribute#rollbackOn