Spring框架內的PROPAGATION_REQUIRES_NEW實現原理


說到Spring框架內的事務隔離級別,估計沒幾個人不知道。但就其實現原理(看spring源碼的實現方式)都覺得頭痛。網上很多源碼分析也分析的不錯,但個人感覺都沒有說到重點。或者換種更讓人簡單理解的方式。
好了廢話不多說。我們來看個例子

      @Transactional
      public void a() {
           //更新數據
            b();
            //...
            //回滾數據             
      }

      @Transactional(propagation = Propagation.REQUIRES_NEW)    
      public void b() {
           //更新數據
      }

大家看到上面的代碼塊,很容的明白,a方法事務不管是回滾還是提交與b方法互不干涉。同理b方法也是一樣
其它的如PROPAGATION_NESTED這種,網上都說了借助於mysql的savepoint。唯獨PROPAGATION_NEW說的玄乎。。
網上都說b方法把a方法內的事務給掛起來了。其實怎么掛的,很少有人說。
...
...
這里省略N字
...
...
其實很簡單,創建兩個連接。
例子如下:

public class TransactionTest {

    @Test
    public void test() throws Exception {
        Connection conn = getConnection();
        conn.setAutoCommit(false);
        Statement statement = conn.createStatement();
        statement.executeUpdate("update test_tl set addr='abc' where id=2");
        transaction2();
        conn.rollback();
    }

    public void transaction2() throws Exception {
        Connection conn = getConnection();
        conn.setAutoCommit(false);
        Statement statement = conn.createStatement();
        statement.executeUpdate("update test_tl set addr='abc' where id=1");
        conn.commit();
    }


    private Connection getConnection() throws Exception {
        String URL = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull";
        String NAME = "test";
        String PASSWORD = "test";
        //1.加載驅動程序
        Class.forName("com.mysql.jdbc.Driver");
        //2.獲得數據庫的連接
        return DriverManager.getConnection(URL, NAME, PASSWORD);
    }
}

這么一說大家就都明白了吧。。呵呵。。。。
不過Spring是開源框架所以就復雜了,不過它的里面用到了大量的ThreadLocal來保存上一個DB鏈接。
好了,不多說了。說到這里有興趣的朋友們可以帶着問題去看一下Spring AbstractPlatformTransactionManager這個類的getTransaction方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM