@Transactional 注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
// 指定事务管理器,mybatis 场景下默认的事务管理器是 DataSourceTransactionManager
@AliasFor("transactionManager")
String value() default "";
// 和 value 互为别名
@AliasFor("value")
String transactionManager() default "";
// 传播行为
Propagation propagation() default Propagation.REQUIRED;
// 隔离级别,DEFAULT 指使用数据库的
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 {};
}
-
事务管理器
TransactionManager 顶级接口没有任何方法,有两个子接口 PlatformTransactionManager 和 ReactiveTransactionManager
ReactiveTransactionManager:WebFlux 场景下非阻塞式的事务管理器,高大上但是不主流
PlatformTransactionManager:平台事务管理器,传统的 web 场景,阻塞式编程模型,常用的有如下子类实现
- DataSourceTransactionManager:用于管理 JDBC 的事务,mybatis 就是用的 JDBC
- JpaTransactionManager:用于 JPA 事务
- HibernateTransactionManager:专用于 Hibernate 的事务
-
传播行为
事务不生效,或者发生异常时有的回滚有的不回滚
A{ B(){ //REQUIRED F();//REQUIRES_NEW G();//REQUIRED H();//REQUIRES_NEW } C(){ //REQUIRES_NEW I()://REQUIRES_NEW J();//REQUIRED } D(){ //REQUIRES_NEW K();//REQUIRES_NEW L();//REQUIRES_NEW // 10/0; K,F,H,C(I,J)= ok,E整个代码走不到 E(){//REOUIRED M();//REQUIRED // 10/0;F,H,C(I,J),D(K,L) = ok N();//REQUIRES_NEW } int i=10/0; // C(I,J),D(K,L),F,H,N= ok }
-
超时时间
事务配置的超时时间是 3 秒,test 方法整个执行要 10S,数据并不会回滚,因为计算的是方法开始到最后一次事务结束的时间
@Transactional(timeout = 3) public void test{ // 业务只需要 2S userDao.updateUser(xxx); // 休眠 10S Thread.sleep(10s); }