spring事務回滾問題


 

剛剛接到一個上家公司同事的一個電話,問我為什么service方法事務不會滾了,日志打印了,調用webservice報錯。

我讓他把這個調用執行webservice的方法截圖發給我,如下:
 
public Object[] send(String operationName,Object[] params,String endPoint) throws Exception {
		Object[] results = null;
		Client client = null;
		try {
			// 獲取外部服務注冊信息
			Map<String, ExtWebserviceInfo> extMap = (Map<String, ExtWebserviceInfo>)SimpleCacheUtils.get(ExtWebService.WEBSERVICE);
			// 獲取操作名稱
			if (!ToolUtil.isNullOrEmpty(extMap)) {
				// 獲取服務方法名
				String methodName = extMap.get(operationName).getServiceValue();
				LOGGER.info("獲取到方法標識為*"+operationName+"的操作名"+methodName);
				// 創建client
				client = new Client(new URL(endPoint));
				LOGGER.info("監測到請求"+endPoint+"服務"+methodName+"操作方法的動作...");
				// 執行調用
				results = client.invoke(methodName, params);
				LOGGER.info("向"+endPoint+"服務"+methodName+"操作方法發出的請求成功...");
			}
		} catch (Exception e) {
			LOGGER.info("向"+endPoint+"服務標識為"+operationName+"的操作方法發出的請求出現異常..."+e.getLocalizedMessage());
			throw(Exception)new Exception().initCause(e);
		} finally{
			if(client != null){
				client.close();
			}
		}
		return results;
	}

  

 
這個方法是一個調用執行webservice的方法,並返回執行結果給調用者,就是上面這個方法報錯。我一看到這個代碼,中有try catch,我想一定是這個方法中把異常給攔截了,service中捕獲不到異常,導致aop攔截不到異常信息,導致事務不回滾。
但是仔細一看發現這個方法雖然捕獲了異常,但是捕獲后有重新拋出異常。
 
} catch (Exception e) {
	LOGGER.info("向"+endPoint+"服務標識為"+operationName+"的操作方法發出的請求出現異常..."+e.getLocalizedMessage());
	throw(Exception)new Exception().initCause(e);
} finally{

   

這不是又拋出異常了嗎?應該沒有問題了啊。
仔細分一下,就發現問題就出在這里,它拋出的是一個Exception,而spring在事務回滾時,是只對runtimeException或者其子類的異常才會回滾。
而且這里拋出的是一個Exception,別人調用的時候肯定提示要trycatch,如果一不小心,catch中沒有重新拋出runtimeException,那就會出現事務不回滾的問題,而且此問題一般不易被發現。
 
總結一下:
1、spring做aop事務攔截的一般都會配置在service層;
2、service層一般情況下不能trycatch,有時候有檢查行異常,那么就往上拋,如果又不想拋,那么就trycatch中在throw new RuntimeException("出錯了!!!");
3、service層拋出的異常必須是runtimeException或者其子類的異常。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM