1. 程式人生 > 其它 >spring事務失效的原因與場景

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();
        }
    }

參考

Spring事務失效的原因(7個):https://www.jianshu.com/p/4120b89190d0