SSM學習記錄(五)——通過註解及AOP進行事務管理
2018.5.4
僅為個人理解 不足之處歡迎指正~
什麼是事務管理?
事務管理是對於一系列資料庫操作進行管理,一個事務包含一個或多個SQL語句,是邏輯管理的工作單元(原子單元)
事務管理的核心在於 回 滾
什麼情況下需要事務管理?
對資料庫中的資料進行批量操作或多表操作時,為了保證資料的正確性和一致性,需要新增事務管理機制進行管理
舉例說明:
銀行轉賬操作細分為兩個步驟:(A向B轉賬100元)
(1)A使用者賬戶餘額減少100元
(2)B使用者賬戶餘額增加100元
那麼假如當執行完(1)步驟而未完成(2)步驟時
情況發生變化 如伺服器宕機 或者使用者取消轉賬
那此時A的餘額減少而B的餘額沒有增加 勢必會造成錯誤
不進行事務管理的情況
由於之前的專案是各種登入註冊之類的業務 較難模擬真實的需要事務管理的操作
我們假想以下操作:
連續註冊兩個使用者 其中第一個使用者合理 第二個使用者的使用者名稱超過了資料庫中定義的最大長度
將這兩個插入過程等價於轉賬中的減少餘額與增加餘額
第二個插入失敗 則第一個插入的結果應該撤銷
在UserService.java中增加一個測試方法:
和他的實現:
編寫Controller接受指令:
package controller; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import pojo.User; import service.UserService; @Controller public class TestController { @Resource UserService userService; @RequestMapping("/shiwuguanli") public ModelAndView shiwuguanli() { ModelAndView mv = new ModelAndView("welcome"); userService.add2User(); return mv; } }
執行程式並測試:
伺服器報錯 此時檢視資料庫:
發現第一個插入操作完成 第二個未完成
使用註解進行事務管理
第一步:
在spring-mybatis配置檔案中加入:
注:jdbcDataSource為自己配置的資料池名稱
第二步:
在所需事務管理的方法上加註解@Transactional
再次執行測試
頁面同樣報錯,但資料庫中沒有出現任何一條插入資訊
注意點:
1.註解需要加在Service的實現中 而不是介面或其他位置
2.不要使用try catch捕獲異常 這樣將不會進行事務回滾
若需要捕獲異常又需要事務回滾 推薦使用以下方法:
@Transactional @Override public void add2User()//事務管理測試 { try { User user=new User("放得下","mima1","電話1","郵箱1"); User user2=new User("放不下放不下放不下放不下放不下放不下放不下放不下", "mima1","電話1","郵箱1"); userdao.addUser(user); userdao.addUser(user2); } catch(Exception e) { System.out.println("伺服器異常"); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }
通過
手動回滾
頁面不會報錯 資料庫中也不會多出資料
使用AOP進行事務管理
我們將剛才的@Transactional去除
開始使用AOP方式進行事務管理:
在spring-mybatis的配置檔案中加入以下語句:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="shiwuguanli"
expression="execution(* service.UserService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="shiwuguanli"/>
</aop:config>
其中:
代表“add開頭 任意字尾的方法” 我們之前使用的方法是add2User 所以包含在這之中
<tx:method>中的標籤有很多
name:方法名的匹配模式,通知根據該模式尋找匹配的方法。
propagation:設定事務定義所用的傳播級別。
isolation:設定事務的隔離級別。
timeout:指定事務的超時(秒)。
read-only:該屬性為true指示事務是隻讀的
no-rollback-for:以逗號分隔的異常類的列表,目標方法可以跑出這些異常而不會導致通知執行回滾
rollback-for:以逗號分隔的異常類的列表,當目標方法跑出這些異常時會導致通知執行回滾。預設情況下,該列表為空,因此不在no-rollback-for列表中的任何執行時異常都會導致回滾。
這裡不做詳細解釋 一般可以採用預設的配置形式
這裡表示的是將剛才的txAdvice織入
在呼叫UserService中所屬的所有方法時會呼叫事務管理 但是要滿足上面的name
執行測試成功 頁面沒有報錯資訊 資料庫中沒有插入資料
同時控制檯輸出了捕獲的異常
其他程式碼:
本文基於之前的各篇SSM學習記錄 其他程式碼沒有做出改動
專案結構如下:
這一個測試中沒有建立新的view層頁面 僅用瀏覽器指令完成
總結:
本文僅演示了一種簡單的需要事務管理的情景
而事物的四大特徵:原子性、一致性、隔離性、永續性
還可以衍生出其他很多種需要事務管理的情況
尤其是隔離性所要求的 本業務的資料不會受到其他業務的干擾 非常重要
具體情況具體分析
謝謝~