@Transactional中的propagation属性

@Transactional中的propagation属性


在Spring的事务管理中,我们可以使用@Transactional这一annotation来对事务进行声明式的设定。具体而言,就是在类或者方法前添加@Transactional并传入属性参数以获取所需要的Transaction特性。Spring中的@Transactional有5个属性:Propagation、Isolation、Rollback Rules、Timeout和Read-Only,其中Propagation属性定义了Transaction的边界 — 是否使用Transaction、在Transaction已存在的情况下如何表现等。

在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。

Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked

如果遇到checked意外就不回滚。

如何改变默认规则:

1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)

2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)

在整个方法运行前就不会开启事务

   还可以加上:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true),这样就做成一个只读事务,可以提高效率。 

   各种属性的意义: 

   REQUIRED:业务方法需要在一个容器里运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务。 

   NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为他开启事务,如果方法在一个事务中被调用,该事务会被挂起,调用结束后,原先的事务会恢复执行。 

   REQUIRESNEW:不管是否存在事务,该方法总汇为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务挂起,新的事务被创建。 

   MANDATORY:该方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果在没有事务的环境下被调用,容器抛出例外。 

   SUPPORTS:该方法在某个事务范围内被调用,则方法成为该事务的一部分。如果方法在该事务范围外被调用,该方法就在没有事务的环境下执行。 

   NEVER:该方法绝对不能在事务范围内执行。如果在就抛例外。只有该方法没有关联到任何事务,才正常执行。 

   NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。 

观察以下两个定义了@Transactional的方法,innerMethod()模拟了Transaction已经存在的情况,outMethod()则模拟了不存在已定义Transaction的情况:

@Transactional
public void outMethod() {
exampleDAO.doSomething();
innerMethod();
}

@Transactional
public void innerMethod() {
exampleDAO.doElse();
}
对于这两个方法,定义不同的Propagation属性值所产生的效果如下(Propagation.NESTED的情况较为复杂,在此忽略):

ropagation属性outMethodinnerMethod
Propagation.MANDATORY抛出异常在outMethod的Transaction中运行
Propagation.NEVER不在Transaction中运行抛出异常
Propagation.NOT_SUPPORTED不在Transaction中运行.outMethod的Transaction暂停直至innerMethod执行完毕
Propagation.REQUIRED ( 默认值 )新开一个Transaction并在其中运行在outMethod的Transaction中运行
Propagation.REQUIRES_NEW.新开一个Transaction并在其中运行.outMethod的Transaction暂停直至innerMethod中新开的Transaction执行完毕
Propagation.SUPPORTS不在Transaction中运行在outMethod的Transaction中运行

@Transactional的代码定义:

[html] view plaincopy在CODE上查看代码片派生到我的代码片

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

/**  
 * A qualifier value for the specified transaction.  
 * <p>May be used to determine the target transaction manager,  
 * matching the qualifier value (or the bean name) of a specific  
 * {@link org.springframework.transaction.PlatformTransactionManager}  
 * bean definition.  
 */  
String value() default "";  

/**  
 * The transaction propagation type.  
 * Defaults to {@link Propagation#REQUIRED}.  
 * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()  
 */  
Propagation propagation() default Propagation.REQUIRED;  

/**  
 * The transaction isolation level.  
 * Defaults to {@link Isolation#DEFAULT}.  
 * @see org.springframework.transaction.interceptor.TransactionAttribute#getIsolationLevel()  
 */  
Isolation isolation() default Isolation.DEFAULT;  

/**  
 * The timeout for this transaction.  
 * Defaults to the default timeout of the underlying transaction system.  
 * @see org.springframework.transaction.interceptor.TransactionAttribute#getTimeout()  
 */  
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;  

/**  
 * {@code true} if the transaction is read-only.  
 * Defaults to {@code false}.  
 * <p>This just serves as a hint for the actual transaction subsystem;  
 * it will <i>not necessarily</i> cause failure of write access attempts.  
 * A transaction manager which cannot interpret the read-only hint will  
 * <i>not</i> throw an exception when asked for a read-only transaction.  
 * @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly()  
 */  
boolean readOnly() default false;  

/**  
 * Defines zero (0) or more exception {@link Class classes}, which must be a  
 * subclass of {@link Throwable}, indicating which exception types must cause  
 * a transaction rollback.  
 * <p>This is the preferred way to construct a rollback rule, matching the  
 * exception class and subclasses.  
 * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class clazz)}  
 */  
Class<? extends Throwable>[] rollbackFor() default {};  

/**  
 * Defines zero (0) or more exception names (for exceptions which must be a  
 * subclass of {@link Throwable}), indicating which exception types must cause  
 * a transaction rollback.  
 * <p>This can be a substring, with no wildcard support at present.  
 * A value of "ServletException" would match  
 * {@link javax.servlet.ServletException} and subclasses, for example.  
 * <p><b>NB: </b>Consider carefully how specific the pattern is, and whether  
 * to include package information (which isn't mandatory). For example,  
 * "Exception" will match nearly anything, and will probably hide other rules.  
 * "java.lang.Exception" would be correct if "Exception" was meant to define  
 * a rule for all checked exceptions. With more unusual {@link Exception}  
 * names such as "BaseBusinessException" there is no need to use a FQN.  
 * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(String exceptionName)}  
 */  
String[] rollbackForClassName() default {};  

/**  
 * Defines zero (0) or more exception {@link Class Classes}, which must be a  
 * subclass of {@link Throwable}, indicating which exception types must <b>not</b>  
 * cause a transaction rollback.  
 * <p>This is the preferred way to construct a rollback rule, matching the  
 * exception class and subclasses.  
 * <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(Class clazz)}  
 */  
Class<? extends Throwable>[] noRollbackFor() default {};  

/**  
 * Defines zero (0) or more exception names (for exceptions which must be a  
 * subclass of {@link Throwable}) indicating which exception types must <b>not</b>  
 * cause a transaction rollback.  
 * <p>See the description of {@link #rollbackForClassName()} for more info on how  
 * the specified names are treated.  
 * <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(String exceptionName)}  
 */  
String[] noRollbackForClassName() default {};  

}
基于源代码,我们可以发现在@Transactional,原来有这么多的属性可以进行配置,从而达到复杂应用控制的目的。

  • 8
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
@注解Propagation属性定义了事务的传播行为。它决定了在一个方法调用另一个被@Transaction注解的方法时,事务是如何被传播的。常见的Propagation属性值有以下几种: 1. REQUIRED:默认值。如果当前没有事务存在,则创建一个新的事务并在其执行方法,如果有事务存在,则加入该事务并在其执行方法。 2. REQUIRES_NEW:每次都创建一个新的事务,并在其执行方法,如果当前有事务存在,则将其挂起。 3. SUPPORTS:如果当前有事务存在,则加入该事务并在其执行方法,如果当前没有事务存在,则以非事务的方式执行方法。 4. MANDATORY:必须在一个事务执行方法,如果当前没有事务存在,则抛出异常。 5. NOT_SUPPORTED:以非事务的方式执行方法,如果当前有事务存在,则将其挂起。 根据不同的Propagation属性,@Transactional注解可以控制事务的传播行为,从而实现不同的事务管理策略。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [@Transactionalpropagation属性](https://blog.csdn.net/windflybird/article/details/101775113)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值