1 @transactional

  1. public @interface Transactional {
  2. @AliasFor("transactionManager")
  3. String value() default "";
  4. @AliasFor("value")
  5. String transactionManager() default "";
  6. Propagation propagation() default Propagation.REQUIRED;
  7. Isolation isolation() default Isolation.DEFAULT;
  8. int timeout() default -1;
  9. boolean readOnly() default false;
  10. Class<? extends Throwable>[] rollbackFor() default {};
  11. String[] rollbackForClassName() default {};
  12. Class<? extends Throwable>[] noRollbackFor() default {};
  13. String[] noRollbackForClassName() default {};
  14. }

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)规范的实现类

2.5 事物 - 图1

3.1 一种AOP环绕增强,对应接口为MethodInterceptor,

事务增强对该接口的实现为TransactionInterceptor

3.2 拦截器 模板方法

事务拦截器TransactionInterceptor在invoke方法中,通过调用父类TransactionAspectSupport的invokeWithinTransaction方法进行事务处理,该方法支持声明式事务和编程式事务。

  1. // TransactionInterceptor.class
  2. @Override
  3. public Object invoke(final MethodInvocation invocation) throws Throwable {
  4. // 获取targetClass
  5. ...
  6. // Adapt to TransactionAspectSupport's invokeWithinTransaction...
  7. return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
  8. @Override
  9. public Object proceedWithInvocation() throws Throwable {
  10. // 实际执行目标方法
  11. return invocation.proceed();
  12. }
  13. });
  14. }
  15. // TransactionInterceptor父类TransactionAspectSupport.class
  16. protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
  17. throws Throwable {
  18. // If the transaction attribute is null, the method is non-transactional.
  19. // 查询目标方法事务属性、确定事务管理器、构造连接点标识(用于确认事务名称)
  20. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
  21. final PlatformTransactionManager tm = determineTransactionManager(txAttr);
  22. final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
  23. if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
  24. // 事务获取
  25. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
  26. Object retVal = null;
  27. try {
  28. // 通过回调执行目标方法
  29. retVal = invocation.proceedWithInvocation();
  30. }
  31. catch (Throwable ex) {
  32. // 目标方法执行抛出异常,根据异常类型执行事务提交或者回滚操作
  33. completeTransactionAfterThrowing(txInfo, ex);
  34. throw ex;
  35. }
  36. finally {
  37. // 清理当前线程事务信息
  38. cleanupTransactionInfo(txInfo);
  39. }
  40. // 目标方法执行成功,提交事务
  41. commitTransactionAfterReturning(txInfo);
  42. return retVal;
  43. } else {
  44. // 带回调的事务执行处理,一般用于编程式事务
  45. ...
  46. }
  47. }

主要逻辑:

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