spring事務失效的原因與場景
技術標籤:Spring
spring事務失效的原因與場景
Spring的事務在什麼樣的情況下會失效?
1底層資料庫不支援事務
如MySQL的MyISAM 引擎是不支援事務操作的,如果底層使用MySQL資料庫和MyISAM 引擎。那麼spring事務事務管理會失效。
2沒有被spring管理
如下面例子所示:
// @Service
public class OrderServiceImpl implements OrderService {
@Transactional
public void updateOrder(Order order) {
// update order;
}
}
如果此時把 @Service
註解註釋掉,這個類就不會被載入成一個 Bean,那這個類就不會被 Spring 管理了,事務自然就失效了。
3方法不是public
– 該異常一般情況都會被編譯器幫忙識別
以下來自 Spring 官方文件:
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do
annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the
annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need
to annotate non-public methods.
翻譯:
在使用代理時,應該只對具有公共可見性的方法應用@Transactional註釋。如果使用@Transactional註釋了受保護的、私有的或包可見的方法,則不會引發錯誤,但註釋的方法不會顯示配置的事務設定。如果需要註釋非公共方法,請考慮使用AspectJ。
如:
4沒加事務的方法呼叫了其他加事務的方法
方法A沒有新增事務註解,但是它呼叫了加事務的方法B。那麼此時B方法事務會失效:
public void methodA(){
methodB();
}
@Transactional(rollbackFor = Exception.class)
public void methodB(){
System.out.println("事務失效");
}
5資料來源,沒有配置事務管理器
事務生效,必須配置資料來源管理器:
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
6主動不支援事務
如使用@Transactional(propagation = Propagation.NOT_SUPPORTED)
傳播屬性NOT_SUPPORTED
不支援事務
當前若存在事務則掛起,
7異常被捕獲
@Transactional(rollbackFor = Exception.class)
public void testTransactionException(){
try {
System.out.println("事務失效");
} catch (Exception e) {
e.printStackTrace();
}
}
8異常型別錯誤或格式錯誤
預設回滾的是:RuntimeException。如果要其他異常生效。需要配置rollbackFor = SQLException.class
或者它的父類LException
@Transactional()
//@Transactional(rollbackFor = SQLException.class)
// @Transactional(rollbackFor = Exception.class)
public void testTransactionDefaultException(){
try {
System.out.println("111");
throw new SQLException("事務失效");
} catch (SQLException e) {
e.printStackTrace();
}
}