spring事物回滾操做-@Transactional

1.關於事物回滾在application.xml中的配置java

<!-- (事務管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
spring

    <tx:annotation-driven transaction-manager="transactionManager"/>數據庫

還有其餘的配置方法,根據我的習慣我喜歡這種方式,固然我是與mybatis結合。編程

上面這種方式官方名稱叫編程式事務,也就是使用註解的方式配置事務,想要使用註解,則必須使用<tx:annotation-driven transaction-manager="transactionManager"/>mybatis

2.怎樣使用註解?app

我在下面給出案例,測試一下:測試

@Transactional
public class Test extends BasicTest{
spa

    @org.junit.Test
    public void testRollBack() throws CustomException{
        
        Country country = new Country();
        country.setId(184);
        country.setCountrycode("B");
        country.setCountryname("ABC");
        
        try{
            countryMapper.insert(country);
            int i = 4/0;
            
        }catch(RuntimeException e){
            throw new CustomException("country插入失敗");
        }
code

}orm

測試的結果爲:不會向數據庫寫入數據,即便沒有

try{

}catch(RuntimeException e){
            throw new CustomException("country插入失敗");
 }

也不會向數據庫寫入數據,網上有人說什麼必須拋出RuntimeException及其子類才能發生回滾,最近,有個比我工做時間長的老師傅說,必需要throw或者try..catch才能發生回滾,都是瞎扯。至於爲何要try..catch或者throw就是想讓咱們看到這裏異常了,容易定位錯誤。

@Transactional,沒有配置參數用做默認的事務回滾

下面是幾種常見的事務類型:

1.PROPAGATION_REQUIRED

支持當前事務,若是當前沒有事務,就新建一個事務。

@org.junit.Test
     @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
        public void testRollBack1() throws CustomException{
            
            Country country = new Country();
            country.setId(184);
            country.setCountrycode("B");
            country.setCountryname("ABC");
            
            countryMapper.insert(country);
            int i = 4/0;
            
    }

執行結果爲:不會向數據庫寫入數據

2.PROPAGATION_SUPPORTS

支持當前事務,若是當前沒有事務,就以非事務方式執行。

@org.junit.Test
        @Transactional(propagation=Propagation.SUPPORTS,rollbackForClassName="Exception")
        public void testRollBack1() throws CustomException{
            
            Country country = new Country();
            country.setId(184);
            country.setCountrycode("B");
            country.setCountryname("ABC");
            
            countryMapper.insert(country);
            int i = 4/0;
            
        }

測試結果是:會向數據庫寫入數據

也就是解釋了若是當前沒有事務,就以非事務方式執行

3.PROPAGATION_MANDATORY

支持當前事務,若是當前沒有事務,就拋出異常。

@org.junit.Test
        @Transactional(propagation=Propagation.MANDATORY,rollbackForClassName="Exception")
        public void testRollBack1() throws CustomException{
            
            Country country = new Country();
            country.setId(184);
            country.setCountrycode("B");
            country.setCountryname("ABC");
            
            countryMapper.insert(country);
            int i = 4/0;
            
        }

測試結果爲:不會向數據庫寫入數據,而且發生異常

org.springframework.transaction.IllegalTransactionStateException: No existing transaction         found for transaction marked with propagation 'mandatory'
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:359)

4.PROPAGATION_REQUIRES_NEW

新建事務,若是當前存在事務,把當前事務掛起。

@org.junit.Test
        @Transactional(propagation=Propagation.REQUIRES_NEW,rollbackForClassName="Exception")
        public void testRollBack1() throws CustomException{
            
            Country country = new Country();
            country.setId(184);
            country.setCountrycode("B");
            country.setCountryname("ABC");
            
            countryMapper.insert(country);
            int i = 4/0;
            
        }

測試結果爲:不會向數據庫寫入數據

5.PROPAGATION_NOT_SUPPORTED

以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。

@org.junit.Test
        @Transactional(propagation=Propagation.NOT_SUPPORTED,rollbackForClassName="Exception")
        public void testRollBack1() throws CustomException{
            
            Country country = new Country();
            country.setId(184);
            country.setCountrycode("B");
            country.setCountryname("ABC");
            
            countryMapper.insert(country);
            int i = 4/0;
            
        }

測試結果爲:會向數據庫寫入數據

6.PROPAGATION_NEVER

以非事務方式執行,若是當前存在事務,則拋出異常。

@org.junit.Test
        @Transactional(propagation=Propagation.NEVER,rollbackForClassName="Exception")
        public void testRollBack1() throws CustomException{
            
            Country country = new Country();
            country.setId(184);
            country.setCountrycode("B");
            country.setCountryname("ABC");
            
            countryMapper.insert(country);
            int i = 4/0;
            
        }

測試結果爲:會向數據庫寫入數據

7.PROPAGATION_NESTED

    若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則進行與PROPAGATION_REQUIRED相似的操做。

@org.junit.Test
        @Transactional(propagation=Propagation.NESTED,rollbackForClassName="Exception")
        public void testRollBack1() throws CustomException{
            
            Country country = new Country();
            country.setId(184);
            country.setCountrycode("B");
            country.setCountryname("ABC");
            
            countryMapper.insert(country);
            int i = 4/0;
            
        }

測試結果爲:會向數據庫寫入數據

相關文章
相關標籤/搜索