Spring中的事务有两种实现方式:编程式事务、声明式事务。
编程式事务:在代码中显式地指定事务的开始、提交和回滚。声明式事务:通过 AOP 和 XML 或 @Transactional 注解来实现,使得开发人员可以将事务管理与业务逻辑解耦。
补充:编程式事务实现代码示例如下:
import org.springframework.transaction.support.TransactionTemplate;
@Autowired
private TransactionTemplate transactionTemplate;
public void doSomething () {
transactionTemplate.execute(status->{
// TODO: 事务内逻辑
});
}
@Transactional 是
org.springframework提供的spring-tx包中的注解,在 Mybatis Plus 包中包含该依赖。
- 可用于修饰方法和类。修饰类时,被修饰类的所有 public 方法都会有事务,建议修饰在方法上。
- 被修饰的方法在抛出异常之后,已经执行的sql会自动回滚。
- 使用方式:@Transactional(rollbackFor=Exception.class)
SpringBoot 中默认开启事务。
rollbackFor属性 用于指定能够触发事务回滚的一出场类型,可以指定多个,用逗号分隔。
- rollbackFor 默认值为 UncheckedException,包括了 RuntimException 和 Error。
- 当我们直接使用 @Transactional 不指定 rollbackFor 时,Exception 及其子类都不会触发。

补充:关于异常的知识

运行时异常(RuntimeException 及其子类)和非运行时异常(Exception 中除了 Runtime Exception 及其子类之外的类)。检查异常(checked exceptions),一定要 try/catch,因为这类异常是可预料的,编译阶段就检查的出来。非检查异常(unchecked exceptions),不需要 try/catch,因为这类异常是不可预料的,编辑阶段不会检查。
rollbackFor 实验结果:
rollbackFor 实验结果说明:
不加 rollbackFor,使用默认值,当出现检查时异常,不会回滚;rollbackFor=Exception.class 不会覆盖 Error 的回滚;@Transactional(rollbackFor=Exception.class)@Transactional 是 通过 AOP 的方式来实现管理事务的,具体来看如下代码:

事务aop处理类 TransactionInterceptor:
package org.springframework.transaction.interceptor;
@SuppressWarnings("serial")
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
}
调用 TransactionAspectSupport 的 invokeWithinTransaction 分三种情况:
响应式编程事务处理命令式编程事务处理没有事务的方法处理实验过程: 这里主要是通过一系列实验来了解@Transactional的事务传播,过程为父方法-调用->子方法,通过分别在父方法和子方法中添加注解和抛出异常来进行测试。
实验结果:(Service内相互调用)
(根据AOP原理,Service间相互调用@Transactional注解修饰的方法事务是生效的)
实验说明:
事务是否回滚,取决于是否是跨实体调用,只有跨实体调用的方法事务才生效;
整理完毕,完结撒花。
参考地址:
1.@Transaction 源码解析:https://blog.csdn.net/shandian534/article/details/124085838
2.@Transactional(rollbackFor):https://blog.csdn.net/qq_43900956/article/details/120993392
3.@Transactional 注解的 rollbackFor 属性:https://www.jianshu.com/p/c5988db897fc
4.啪!啪!@Transactional 注解的12种失效场景,这坑我踩个遍:https://blog.51cto.com/u_14787961/4833414