@Transactional事务注解源码如下
@Target({ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic@interfaceTransactional{@AliasFor("transactionManager")Stringvalue()default"";@AliasFor("value")StringtransactionManager()default"";String[]label()default{};Propagationpropagation()defaultPropagation.REQUIRED;Isolationisolation()defaultIsolation.DEFAULT;inttimeout()default-1;StringtimeoutString()default"";booleanreadOnly()defaultfalse;Class<?extendsThrowable>[]rollbackFor()default{};String[]rollbackForClassName()default{};Class<?extendsThrowable>[]noRollbackFor()default{};String[]noRollbackForClassName()default{};}
各属性详解
value:事务管理器名称;
transactionManager:同value,事务管理器名称,和value选配一个就行,或者都为空,默认从容器中查找事务管理器;
label:
propagation:事务的传播性;
isolation:事务的隔离级别;
timeout:事务超时时间;
readOnly:是否是只读事务;
rollbackFor:指定回滚事务的异常;
rollbackForClassName:指定回滚事务的异常类名;
noRollbackFor:指定不回滚事务的异常;
noRollbackForClassName:指定不回滚事务的异常类名;
声明式事务使用方式
通常我们使用@Transactional注解时,加在方法或者类上面,加在方法上表示当前方法需要以事务方式运行,加在类上面,表示此类下面所有方法都要以事务方式运行。
情形一
如果我们希望发生异常时,事务自动回滚,则配置如下属性
@Transactional(rollbackFor =Exception.class)
情形二
有时候我们在一个事务方法中,希望某个被调用的方法,以一个新的事务方式运行,我们可以配置如下propagation事务传播属性,表示新开启一个事务
@Transactional(rollbackFor =Exception.class,propagation =Propagation.REQUIRES_NEW)
情形三
如果我们在进行一组操作时,每个操作都是一个事务,并且希望每个操作之间能够读取对方未提交的数据,则可进行如下isolation事务隔离级别的配置
@Transactional(rollbackFor =Exception.class,propagation =Propagation.REQUIRES_NEW,isolation =Isolation.READ_UNCOMMITTED)
情形四
在事务方法中开启子线程时,子线程开启了新的事务,是否回滚不受当前方法的事务控制
@Transactional(rollbackFor =Exception.class)
publicvoidtest(){
executor.execute(()->{// 子线程业务代码});}
事务失效场景
自调用失效
如下两个方法在同一个类中,test1方法的事务失效
publicvoidtest(){test1();}@Transactionalpublicvoidtest1(){}
修饰非public方法
如下,修饰非public方法时,事务不生效
@Transactionalprivatevoidtest(){}
拦截异常未抛出
如下方式异常被拦截未抛出,会导致事务不会回滚
@Transactional(rollbackFor =Exception.class)publicvoidtest1(){try{}catch(Exception e){
log.error("error");}}
版权归原作者 筝子果 所有, 如有侵权,请联系我们删除。