1. 程式人生 > >記一次spring註解開啟失敗的經歷

記一次spring註解開啟失敗的經歷


1.專案中註解開啟事務配置

  如有多個org.springframework.jdbc.datasource.DataSourceTransactionManager時候,要制定bean名稱,例:

@Transaction(“transactionManager”)

2.spring中註解增強方式的缺點

  即類中public方法不能呼叫本類中的其他方法,否則增強無效。

  專案中由於架構設計的原因,程式碼構造如下所示

1 class BaseService{
2     public void doBussiness(){
3           ……
4           doWork();
5 …… 6 } 7 public void doWork(){ 8 } 9 }

   增加service只要繼承該BaseService即可

@Transaction
class ServiceImple extends BaseService{
    @override
    public void doWork(){
        ……
        ……
    }
}

  此時註解開啟失敗,經過分析原因,因為BaseService中doBussiness方法呼叫本類中的doWork方法時,spring並不會增強該方法,無法獲得該方法的代理方法,所以無法回滾事務。

3.解決方法

  所以在架構設計時要避免呼叫本類中抽象方法這種架構模式,這樣子類繼承後得不到增強。

  下面提供一種手動事務管理方式

  3.1有ApplicationContext 情況下

DataSourceTransactionManager transactionManager = (DataSourceTransactionManager) ctx.getBean("txManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); 
// 事物隔離級別,開啟新事務,這樣會比較安全些。 TransactionStatus status = transactionManager.getTransaction(def); // 獲得事務狀態 try { //邏輯程式碼,可以寫上你的邏輯處理程式碼 transactionManager.commit(status); } catch (Exception e) { transactionManager.rollback(status); }

  3.2 沒有ApplicationContext 情況

  

@Autowired //這裡如果有多個Manager,要新增@Qualifier(“txManager”)
private DataSourceTransactionManager txManager;

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);// 事物隔離級別,開啟新事務
TransactionStatus status = txManager.getTransaction(def); // 獲得事務狀態

try{
    //邏輯程式碼,可以寫上你的邏輯處理程式碼
    txManager.commit(status);
}catch(Exception e){
    txManager.rollback(status);
}

  當然也可以做宣告式事務處理,這裡不再贅述!

over,歡迎大家指正,以便寫出更高階的bug!