1.一個有@Transactional的方法被沒有@Transactional方法調用時,會導致Transactional作用失效。也是最容易出現的情況。
那為啥會出現這種情況?其實這還是由於使用Spring AOP
代理造成的,因為只有當事務方法被當前類以外的代碼調用時,才會由Spring
生成的代理對象來管理。
2.對非public方法進行事務注解。@Transactional 將會失效。
原因:是應為在Spring AOP代理時,事務攔截器在目標方法前后進行攔截,DynamicAdvisedInterceptor
的intercept 方法會獲取Transactional注解的事務配置信息,
因為在Spring AOP 代理時,如上圖所示
TransactionInterceptor
(事務攔截器)在目標方法執行前后進行攔截,
DynamicAdvisedInterceptor
(CglibAopProxy 的內部類)的 intercept 方法或
JdkDynamicAopProxy
的 invoke 方法會間接調用
AbstractFallbackTransactionAttributeSource
的
computeTransactionAttribute
方法會間接調用
AbstractFallbackTransactionAttributeSource
的
computeTransactionAttribute
方法,這個方法會獲取Transactional 注解的事務配置信息。他會首先校驗事務方法的修飾符是不是public,不是 public則不會獲取@Transactional 的屬性配置信息。
3.Transactional 事務配置屬性中的propagation 屬性配置的問題。
當propagation屬性配置為:
TransactionDefinition.PROPAGATION_SUPPORTS
:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED
:以非事務方式運行,如果當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_NEVER
:以非事務方式運行,如果當前存在事務,則拋出異常
4.還存在一種情況:
在一個類中A方法被事務注釋,B方法也被事務注釋。
@ Transactional
public void A(){
try{
this.B();
}catch(Exception e){
logger.error();
}
}
但在執行B方法是報錯,但是異常被A catch 住,此時事務也會失效。