1 @transactional
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.DEFAULT;
int timeout() default -1;
boolean readOnly() default false;
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
2 传播行为
2.1 Propagation.REQUIRED(默认)
如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。
2.2 Propagation.SUPPORTS
如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。
2.3 Propagation.MANDATORY
如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。
2.4 Propagation.REQUIRES_NEW
重新创建一个新的事务,如果当前存在事务,延缓当前的事务。
2.5 Propagation.NOT_SUPPORTED
以非事务的方式运行,如果当前存在事务,暂停当前的事务。
2.6 Propagation.NEVER
以非事务的方式运行,如果当前存在事务,则抛出异常。
2.7Propagation.NESTED
如果没有,就新建一个事务;如果有,就在当前事务的分支
3 实现原理
PlatformTransactionManager 事务管理器
AbstractPlatformTransactionManager抽象类实现了Spring事务的标准流程
DataSourceTransactionManageJDBC单数据源事务管理器
JtaTransactionManager是JTA(Java Transaction API)规范的实现类
3.1 一种AOP环绕增强,对应接口为MethodInterceptor,
事务增强对该接口的实现为TransactionInterceptor
3.2 拦截器 模板方法
事务拦截器TransactionInterceptor在invoke方法中,通过调用父类TransactionAspectSupport的invokeWithinTransaction方法进行事务处理,该方法支持声明式事务和编程式事务。
// TransactionInterceptor.class
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
// 获取targetClass
...
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
@Override
public Object proceedWithInvocation() throws Throwable {
// 实际执行目标方法
return invocation.proceed();
}
});
}
// TransactionInterceptor父类TransactionAspectSupport.class
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
// 查询目标方法事务属性、确定事务管理器、构造连接点标识(用于确认事务名称)
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// 事务获取
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// 通过回调执行目标方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 目标方法执行抛出异常,根据异常类型执行事务提交或者回滚操作
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 清理当前线程事务信息
cleanupTransactionInfo(txInfo);
}
// 目标方法执行成功,提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
} else {
// 带回调的事务执行处理,一般用于编程式事务
...
}
}
主要逻辑:
1 获取事务属性,根据事务属性,获取事务管理器。
2 判断属性是否空,或者事务管理器是否不是 CallbackPreferringPlatformTransactionManager 类型,如果是该类型,则会执行事务管理器的 execute 方法。
3 生成一个封装了事务管理器,事务属性,方法签名字符串,事务状态对象 的 TransactionInfo 事务信息对象。该对象会在事务回滚或者失败时起作用。
4 调用目标对象方法或者是下一个过滤器的方法。
5 如果方法由异常则执行 completeTransactionAfterThrowing 方法,调用事务管理器的回滚方法。如果没有异常,调用 commitTransactionAfterReturning 提交方法。最后返回返回值
参考
1 https://blog.csdn.net/acingdreamer/article/details/91873745
2 https://blog.csdn.net/levae1024/article/details/82998386
3 https://zhuanlan.zhihu.com/p/54067384