Spring的Transactional註解不回滾問題

爲了解決這個問題, 網上找了很多資料。
但是你懂得, 百度搜出來的都是同一個問題拷貝來拷貝去。

什麼public方法,unchecked異常都試過了還是不行。

後來在谷歌上找到一個blog
https://ameblo.jp/kochablo/entry-11578714824.html

大致意思是, @Transactional必須是利用通過DI注入完後的對象調用@Transactional註釋的方法。
也就是

問題代碼

// ServiceA代碼
public class ServiceA {
    public void insert() {
        insertTbl1();
        insertTbl2();
        //...
        //......
    }

    @Transactional
    public void insertTbl1() {
        // do something.
    }

    @Transactional
    public void insertTbl2() {
        // do something.
    }
}
// ServiceB代碼
public class ServiceB {
    @Autowired
    ServiceA serviceA;

    public void test() {
        serviceA.insert();
    }
}

需要改成如下

// ServiceA代碼
public class ServiceA {
    // 在ServiceB當中直接通過DI後的對象調用insert, 
    // 所以這個方法上必須要有Transactional,否則不會啓動事務。
    @Transactional
    public void insert() {
        insertTbl1();
        insertTbl2();
        //...
        //......
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertTbl1() {
        // do something.
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insertTbl2() {
        // do something.
    }
}
// ServiceB代碼
public class ServiceB {
    @Autowired
    ServiceA serviceA;

    public void test() {
        // ServiceA的insert方法必須要@Transactional。
        serviceA.insert();
    }
}

Why?
https://dev.classmethod.jp/server-side/declarative-trasaction-by-spring-aop/

另外也可以通過代碼寫上事務管理也可以。

    @Autowired
    PlatformTransactionManager txManager;
    // 使用DefaultTransactionDefinition
    public void insert1() {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = txManager.getTransaction(def);

        try {
            // do some thing..
            txManager.commit(status);
        } finally {
            if (!status.isCompleted()) txManager.rollback();
        }
    }

    // 使用template
    public void insert2() {
        TransactionTemplate template = new TransactionTemplate(txManager);
        template.setName("tx name");
        template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        template.execute(status -> {
            // do something... 
            return "result";
        });
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章