接上一讲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