接上一講aop的轉賬案例, 自己利用spring的aop對轉賬方法進行增強,加入了事務的管理, 如下:
package com.hr.utils;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.SQLException;
/**
* 和事務管理的工具類,它包含了, 開啓事務,提交事務,回滾事務和釋放連接
*/
@Component("txManager")
@Aspect
public class TransactionManager {
@Autowired
private ConnectionUtils connectionUtils;
@Pointcut("execution(* com.hr.service.impl.*.*(..))")
private void pt1(){}
@Before("pt1()")
public void beginTransaction() {
try {
connectionUtils.getThreadConnection().setAutoCommit(false);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
@AfterReturning("pt1()")
public void commit() {
try {
connectionUtils.getThreadConnection().commit();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
@AfterThrowing("pt1()")
public void rollback() {
try {
connectionUtils.getThreadConnection().rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
@After("pt1()")
public void release() {
try {
connectionUtils.getThreadConnection().close(); //吧連接關閉,還回線程池中
connectionUtils.removeConnection(); //把連接和線程解綁
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
而spring中有專門的對事務管理的處理, 針對jdbcTemplate, 使用的是DataSourceTransactionManager
<!--
spring中基於XML聲明式事務控制配置步驟
1 配置事務管理器
2 配置事務的通知
此時我們需要導入事務的約束, tx名稱空間和約束,同時也需要aop的
使用tx:advice標籤配置事務通知
屬性:
id:給事務通知起一個唯一標準
transaction-manager: 給事務通知提供一個事務管理器引用
3 配置AOP中的通用切入點表達式
4 建立事務通知和切入點表達式的對應關係
5 配置事務的屬性
是在事務的通知tx:advice標籤的內部
-->
<!--1 配置事務管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--2 配置事務的通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--5 配置事務的屬性
isolation="" 用於指定事務的隔離級別,默認值是DEFAULT,表示使用數據庫的默認隔離級別
propagation="" 用於指定事務的傳播行爲,默認值是REQUIRED,表示一定會有事務,增刪改的選擇. 查詢方法可以選擇SUPPORTS
read-only="" 事務是否只讀, 只有查詢方法才能設置爲true. 默認值是false,表示讀寫
timeout="" 用於指定事務的超時時間,默認值是-1,表示永不超時. 如果指定了數值,以秒爲單位
rollback-for="" 用於指定一個異常,當產生改異常時,事務回滾, 產生其他異常時,事務不回滾. 沒有默認值.表示任何異常都回滾
no-rollback-for="" 用於指定一個異常,當產生該異常時,事務不回滾,產生其他異常時事務回滾,沒有默認值.表示任何異常都回滾
-->
<tx:attributes>
<!--其他的方法全部是默認值,有事務,並且只讀爲false-->
<tx:method name="*" propagation="REQUIRED" read-only="false" />
<!--所有以find開頭的全部爲查詢方法,傳播行爲爲SUPPORTS, 只讀爲true-->
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--3 配置AOP中的通用切入點表達式-->
<aop:config>
<aop:pointcut id="pt1" expression="execution(* com.hr.service.impl.*.*(..))"/>
<!--4 建立事務通知和切入點表達式的對應關係-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
</aop:config>
上述在XML中配置之後,那麼項目中 所有在impl包下面的所有的類和方法都不會有事務的困擾, 都已經被事務管理
上述案例github地址: https://github.com/2402zmybie/spring04_03account