Spring 編程的方式實現事務管理,這樣太過麻煩,需要在每個方法上面加上相應的事務處理操作,聲明式事務處理能夠很好的解決這個問題,比如通過tx命名空間,這樣只需要配置就可以檢測到相關的方法,或者是通過@transcational注解來實現,這樣會減少很多的代碼量,但是實現的時候有這樣的幾個點需要注意
首先我們來看tx命名空間來實現:
<tx:advice id="transcation" transaction-manager="transcationManager"><tx:attributes><tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"></tx:method></tx:attributes></tx:advice><aop:config><aop:pointcut expression="execution(* com.aa.dao.api.IStudentDao.tranfMoeny(..))" id="transcationCut" /><aop:advisor advice-ref="transcation" pointcut-ref="transcationCut"/></aop:config>
配置如上圖:
需要配置aop:config ,因為Spring 事務管理是基于aop來進行實現的,在aop:config 中我們配置了切點 pointcut 和一個advisor 什么是advisor 呢,我們來看一下:
然后使用tx 來配置事務通知,
<tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 所有以 'get' 開頭的方法使用只讀事務 --><tx:method name="get*" read-only="true"/><!-- 其他方法使用默認的事務屬性 --><tx:method name="*"/></tx:attributes>
</tx:advice>
id
?屬性為事務通知指定一個唯一的標識符。transaction-manager
?屬性指定使用的事務管理器。<tx:attributes>
?標簽內可以定義不同方法名匹配規則下的事務屬性。name
?屬性用于指定方法名的匹配規則,支持通配符?*
。read-only
?屬性用于指定事務是否為只讀事務。
然后我們去執行方法的時候,如果出現了異常就會執行相應的回滾的操作,對于目標方法,我們可以這樣設置:
@Overridepublic void tranfMoeny(String money, String fromname, String targetName) {String sql_sub = "update t_account set money=money-" + money + " where username=\'" + fromname + "\'";jdbcTemplate.execute(sql_sub);Integer.parseInt("jjf");//模擬出現異常String sql_add = "update t_account set money=money+" + money + " where username=\'" + targetName + "\'";jdbcTemplate.execute(sql_add);}
或者:
@Overridepublic void tranfMoeny(String money, String fromname, String targetName) {try {String sql_sub = "update t_account set money=money-" + money + " where username=\'" + fromname + "\'";jdbcTemplate.execute(sql_sub);Integer.parseInt("jjf");String sql_add = "update t_account set money=money+" + money + " where username=\'" + targetName + "\'";jdbcTemplate.execute(sql_add);} catch (Exception e) {e.printStackTrace();throw new RuntimeException("數據插入異常");}}
非常重要的一點是,目標方法需要有異常拋出,我們可以手動拋出,或者默認拋出異常的方式,這樣我們的事務管理器就可以檢測到,并且執行回滾操作。
希望對你有所幫助!