Spring Transaction 源码分析
作为一个开发人员,大家肯定都了解事务的重要性,在我日常开发中,如果您用的是Spring框架, 那您一定知道@Transaction这个注解,但是为什么加了注解我们的方法就具有事务了,相比很多人也不是很清楚, 今天就让我们一起来学习一下@Transaction背后到了做了什么?
起源TransactionInterceptor
介绍 官方的解释:声明性事务的AOP方法拦截器,使用公共Spring事务基础设施进行管理
类图如下:

invoke方法
执行的流程
通过上面的主要代码我们大概知道了一个执行的流程:

核心方法介绍
determineTransactionManager
常用的 PlatformTransactionManager :
注: 多数据源是最好配置多个事务管理器,否则会默认创建一个
createTransactionIfNecessary
getTransaction
判断当前事务是否是一个新的事务,否则加入到一个已经存在的事务中。事务传播级别REQUIRED和REQUIRE_NEW有用到。 当前事务是否携带保存点,嵌套事务用到。 setRollbackOnly,isRollbackOnly,当子事务回滚时,并不真正回滚事务,而是对子事务设置一个标志位。 事务是否已经完成,已经提交或者已经回滚。
prepareTransactionInfo方法
TransactionInfo是对当前事务的描述,其中记录了事务的状态等信息。它记录了和一个事务所有的相关信息。 它没有什么方法,只是对事务相关对象的一个组合。最关键的对象是TransactionStatus,它代表当前正在运行的是哪个事务。
TransactionDefinition
在上面我们看到了这样的代码,TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults()); 但是这具体做了什么,我们接下来分析一下,TransactionDefinition的是Spring中的事务支持的核心接口,并将其定义如下
1个
int getPropagationBehavior()此方法返回传播行为。Spring提供了EJB CMT熟悉的所有事务传播选项。
2
int getIsolationLevel()此方法返回此事务与其他事务的工作隔离的程度。
3
字符串getName()此方法返回此事务的名称。
4
int getTimeout()此方法以秒为单位返回必须完成事务的时间。
5
boolean isReadOnly()此方法返回事务是否为只读。
以下是隔离级别的可能值
1个
TransactionDefinition.ISOLATION_DEFAULT这是默认的隔离级别。
2
TransactionDefinition.ISOLATION_READ_COMMITTED指示防止脏读;可能会发生不可重复的读取和幻像读取。
3
TransactionDefinition.ISOLATION_READ_UNCOMMITTED表示可能发生脏读,不可重复读和幻像读。
4
TransactionDefinition.ISOLATION_REPEATABLE_READ指示防止脏读和不可重复读;可能会发生幻像读取。
5
TransactionDefinition.ISOLATION_SERIALIZABLE指示防止脏读,不可重复读和幻像读。
以下是传播类型的可能值
1个
TransactionDefinition.PROPAGATION_MANDATORY支持当前交易;如果当前事务不存在,则引发异常。
2
TransactionDefinition.PROPAGATION_NESTED如果当前事务存在,则在嵌套事务中执行。
3
TransactionDefinition.PROPAGATION_NEVER不支持当前交易;如果当前事务存在,则引发异常。
4
TransactionDefinition.PROPAGATION_NOT_SUPPORTED不支持当前交易;而是始终以非事务方式执行。
5
TransactionDefinition.PROPAGATION_REQUIRED支持当前交易;如果不存在,则创建一个新的。
6
TransactionDefinition.PROPAGATION_REQUIRES_NEW创建一个新事务,如果存在则暂停当前事务。
7
TransactionDefinition.PROPAGATION_SUPPORTS支持当前交易;如果不存在,则以非事务方式执行。
8
TransactionDefinition.TIMEOUT_DEFAULT使用基础事务系统的默认超时;如果不支持超时,则不使用默认超时。
Last updated