Spring的事务
一,Spring事务使用类型
- 配置型事务:通过xml配置,但现在一般是SpringBoot的环境,基本不通过xml配置
- 声明式事务:在方法上或类上添加 @Transactional
- 编程式事务:通过编写AOP的切点,拦截器。可在切点上拦截某些方法达到局部事务,或拦截全局达到全局事务
- 开启全局事务:在启动类上添加注解 @EnableTransactionManagement
二,@Transactional 属性介绍
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited // 接口可继承
@Documented
public @interface Transactional {
//设置 事务管理器
@AliasFor("transactionManager")
String value() default "";
//设置 事务管理器
@AliasFor("value")
String transactionManager() default "";
//设置 一个标签,标注
String[] label() default {};
//设置 事务的传播方式
Propagation propagation() default Propagation.REQUIRED;
//设置 事务隔离级别
Isolation isolation() default Isolation.DEFAULT;
//设置 事务超时时间
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
//设置 事务超时时间
String timeoutString() default "";
//设置 事务只读
boolean readOnly() default false;
//设置 事务需要回滚的异常
Class<? extends Throwable>[] rollbackFor() default {};
//设置 事务需要回滚的异常
String[] rollbackForClassName() default {};
//设置 事务不需要回滚的异常
Class<? extends Throwable>[] noRollbackFor() default {};
//设置 事务不需要回滚的异常
String[] noRollbackForClassName() default {};
}
-
transactionManager 属性设置事务管理器
-
Isolation属性一共有4种事务隔离级别:
- READ_COMMITTED:读已提交
- READ_UNCOMMITTED:读未提交(Oracle默认级别)
- REPEATABLE_READ:可重复读 (Mysql默认级别)
- SERIALIZABLE:串行化
事务隔离级别可看:事务隔离级别
-
propagation属性一共有7种事务传播方式,根据事务支持类型可分为三种:
-
支持当前事务
-
REQUIRED:支持当前事务,如果不存在则创建一个新事务
-
SUPPORTS:支持当前事务,如果不存在,则以非事务方式执行
-
MANDATORY:支持当前事务,如果不存在则抛出异常
-
不支持当前事务
-
REQUIRES_NEW:创建一个新事务,如果存在则挂起当前事务
-
NOT_SUPPORTED:以非事务方式执行,如果存在当前事务,则挂起当前事务
-
NEVER:以非事务方式执行,如果存在事务,则引发异常
-
嵌套事务
-
NESTED:如果存在当前事务,则在嵌套事务中执行
-
-
timeout 属性设置超时,若事务执行超过时间则自动回滚
-
readOnly属性设置只读
-
@Transactional可以设声明在类上,可以声明在方法上,
-
@Transactional是AOP实现的,AOP基于动态代理实现
三,@Transactional 失效原因
- @Transactional 声明在非 public 的方法上
- 自调用:什么是自调用?同一个类中,有方法A,B,无 @Transactional 的方法A内部调用有 @Transactional 的方法B 的情况。原因是AOP无法为自身生成代理对象进行调用。解决办法,将需要添加@Transactional 方法另起一个类作为被调用类,调用类注入这个另起的被调用类。
- @Transactional 没有声明对回滚的异常类以及子类
四,@Transactional 底层
- ThreadLocal
- 基于AOP