事务 - 声明式事务

@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 场景,阻塞式编程模型,常用的有如下子类实现

    1. DataSourceTransactionManager:用于管理 JDBC 的事务,mybatis 就是用的 JDBC
    2. JpaTransactionManager:用于 JPA 事务
    3. 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);
    }
    
posted @   CyrusHuang  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示