即不需要在原来的业务逻辑代码中加入任何事务相关的代码,而是通过xml,或者注解的方式,来告诉框架,哪些方法需要添加事务处理代码,让框架来完成在原始业务逻辑前后增加事务处理的代码(通过AOP),这也是AOP使用较多的场景之一;
基于tx名称空间的配置配置文件:
需要引入aop和tx名称空间
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context/spring-context.xsd"> <import resource="mybatis-beans.xml"/> <context:component-scan base-package="com.yh.service"/> <!-- 添加事务管理器--> <bean> <property ref="dataSource"/> </bean> <!-- 事务通知--> <tx:advice transaction-manager="transactionManager"> <tx:attributes> <!-- name指定要应用的方法名称 还有其他事务常用属性如隔离级别传播行为等..--> <tx:method read-only="false"/> </tx:attributes> </tx:advice> <!-- 切点信息--> <aop:config > <!-- 根据表达式中的信息可以自动查找到目标对象 从而进行增强 先查找目标再生产代理--> <aop:pointcut expression="execution(* com.yh.service.*.*(..))"/> <aop:advisor advice-ref="transactionAdvice" pointcut-ref="pointcut"/> </aop:config> </beans>tx:method属性:
属性名 含义name 匹配的方法名称
isolation 事务隔离级别
read-only 是否采用优化的只 读事务
timeout 超时
rollback-for 需要回滚的异常类
propagation 传播行为
no-rollback-for 不需要回滚的异常类
Service:
@Service public class StudentService { @Autowired private StudentMapper studentMapper; public Student getStudent(int id ){ return studentMapper.selectByPrimaryKey(id); } public void update(Student student){ studentMapper.updateByPrimaryKey(student); int i = 1/0; } }测试代码:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext3.xml") public class Test3 { @Autowired StudentService studentService; @Test public void test(){ Student student = studentService.getStudent(1); System.out.println(student); student.setAge(8818); studentService.update(student); } }强调:事务增强应该应用到Service层,即业务逻辑层,应为一个业务方法可能涉及多个数据库操作,当某个操作遇到异常时需要将所有操作全部回滚
基于注解的配置Spring当然也支持采用注解形式来处理事务
开启注解事务支持:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context/spring-context.xsd"> <!--为了分离关注点,故将MyBatis相关配置放到其他配置文件了--> <import resource="mybatis-beans.xml"/> <context:component-scan base-package="com.yh.service"/> <!-- 添加事务管理器--> <bean> <property ref="dataSource"/> </bean> <!-- 开启注解事务管理--> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>Service中增加方法:
@Transactional(propagation = Propagation.REQUIRED,readOnly = false) public void transactionTest(){ Student student = getStudent(1); student.setAge(1); update(student); int i = 1/0; student.setName("jack"); update(student); } //当然注解上的参数都是可选的采用默认值即可