當但願在某個方法中添加事務時,咱們經常在方法頭上添加@Transactional註解java
@ResponseBody @RequestMapping(value = "/payment", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @Transactional public Payment paymentJson(@RequestBody PaymentRequestInfo entity) { //method }
容易讓人忽略的是:方法上未加任何屬性的@Transactional註解只能在拋出RuntimeException或者Error時纔會觸發事務的回滾,常見的非RuntimeException是不會觸發事務的回滾的。app
若是要在拋出 非RuntimeException時也觸發回滾機制,須要咱們在註解上添加 rollbackFor = { Exception.class }屬性。spa
@ResponseBody @RequestMapping(value = "/payment", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @Transactional(rollbackFor = { Exception.class }) public Payment paymentJson(@RequestBody PaymentRequestInfo entity) { //method }
固然,上面事務回滾的前提是添加@Transactional註解的方法中不含有try{...}catch{...}捕獲異常,使得程序運行過程當中出現異常能順利拋出,從而觸發事務回滾。3d
在實際開發中,咱們每每須要在方法中進行異常的捕獲,從而對異常進行判斷,爲客戶端返回提示信息。可是此時因爲異常的被捕獲,致使事務的回滾沒有被觸發,致使事務的失敗。code
下面提供幾種解決方法:blog
方法上使用@Transactional註解,在捕獲到異常時在catch語句中拋出RuntimeException。事務
方法上使用@Transactional(rollbackFor = { Exception.class })註解聲明事務回滾級別,在捕獲到異常時在catch語句中直接拋出所捕獲的異常。開發
上面兩個在catch{...}中拋出異常的方法都有個不足之處,就是不能在catch{...}中存在return子句,因此設置手動回滾,當捕獲到異常時,手動回滾,同時返回前臺提示信息。it