記一次spring註解開啟失敗的經歷
阿新 • • 發佈:2018-11-27
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!