Spring事务控制详解:从概念到声明式事务(AOP实现)
一、Spring事务控制在分层开发的Java EE应用中事务处理是业务层的核心职责。Spring框架提供了一套完整的、基于AOP的声明式事务管理方案能让我们在不侵入业务代码的前提下轻松控制事务。1、事务介绍1.1、什么是事务事务是保证一组数据库操作要么全部成功要么全部失败恢复到原点的机制。Spring事务管理的目标可以形象地理解为刘德华在《无间道》中的一句话“去不了终点就回到原点”。事务的四大特性ACID原子性Atomicity事务是最小的执行单位不可分割。一致性Consistency事务执行前后数据库的完整性约束不被破坏。隔离性Isolation并发执行的事务彼此隔离互不干扰。持久性Durability事务一旦提交其结果就是永久性的。1.2、转账案例引发的问题我们通过一个经典的“转账”案例来理解为何需要Spring事务控制。业务很简单从账户A转一笔钱到账户B需要执行两个操作1. A账户扣款2. B账户加款。如果不使用事务当扣款SQL执行成功但加款SQL执行前程序发生异常如除零错误会导致A的钱已扣B的钱未加数据不一致。?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.hg.mapper.UserMapper ... ... !--转账-- update idupdateUserOfSub update t_user set moneymoney-#{money} where name#{source} /update update idupdateUserOfAdd update t_user set moneymoney#{money} where name#{target} /update /mapperpublic interface UserMapper { ... ... /**扣钱*/ void updateUserOfSub(Param(source) String source, Param(money) Float money); /*加钱*/ void updateUserOfAdd(Param(target) String target, Param(money) Float money); }Service public class UserServiceImpl implements UserService { Autowired private UserMapper userMapper; /** * 转账 * param source * param target * param money */ Override public void updateUser(String source, String target, Float money) { userMapper.updateUserOfSub(source, money); int a 6/0; userMapper.updateUserOfAdd(target, money); } }RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(classpath:applicationContext.xml)//加载配置文件 public class ServiceTest { Autowired private UserService userService; /** * 转账业务 */ Test public void testUpdate(){ userService.updateUser(张三丰,宋远桥,1F); } }测试结果2、Spring中事务控制的API介绍Spring的事务管理基于三个核心接口。2.1、PlatformTransactionManager事务管理器这是Spring事务策略的核心接口真正负责管理事务开启、提交、回滚。Spring为不同的持久化框架提供了实现类例如DataSourceTransactionManager适用于Spring JDBC、MyBatis、iBatis。HibernateTransactionManager适用于Hibernate。2.2、TransactionDefinition事务定义)此接口定义了事务的五大核心属性隔离级别Isolation解决事务并发时的安全问题脏读、不可重复读、幻读。Spring提供了ISOLATION_DEFAULT使用数据库默认级别、ISOLATION_READ_COMMITTED等选项。传播行为Propagation定义了一个事务方法被另一个事务方法调用时事务应如何传播。最常用的是PROPAGATION_REQUIRED如果当前没有事务就新建一个如果有就加入其中。超时时间Timeout事务执行的最长时间限制超时则自动回滚。默认值-1表示不超时。只读状态Read-onlytrue表示事务只读用于优化查询false表示可读写用于增删改。回滚规则Rollback rules默认情况下事务在遇到运行时异常RuntimeException时回滚在遇到检查时异常Checked Exception如IOException时不回滚。可通过配置自定义。2.3、TransactionStatus事务状态此接口提供了查询事务状态和控制事务如标记为仅回滚的方法。3、编程式事务管理我们可以直接使用上述API在业务代码中手动控制事务步骤如下在Spring配置文件中配置DataSourceTransactionManager和DefaultTransactionDefinition。在业务方法中通过PlatformTransactionManager.getTransaction()获取事务状态。在try-catch块中执行业务操作成功则commit()失败则rollback()。// 示例编程式事务 public void updateUser(String source, String target, Float money) { TransactionStatus txStatus txManager.getTransaction(txDefinition); try { userMapper.updateUserOfSub(source, money); int a 6/0; // 模拟异常 userMapper.updateUserOfAdd(target, money); txManager.commit(txStatus); // 提交 } catch (Exception e) { txManager.rollback(txStatus); // 回滚 e.printStackTrace(); } }缺点事务控制代码与业务逻辑代码高度耦合重复代码多难以维护。4、声明式事务管理基于AOP声明式事务是Spring推荐的方式其核心思想是将事务管理作为一项横切关注点通过AOP动态代理在目标方法前后进行增强。这样业务代码就完全不需要关心事务了。4.1、配置事务管理器首先在Spring配置文件中声明事务管理器。bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean4.2、配置事务增强使用tx:advice标签定义事务通知指定事务管理器和详细的事务属性规则。tx:advice idtxAdvice transaction-managertransactionManager tx:attributes !-- 对所有方法应用事务 -- tx:method name* read-onlyfalse propagationREQUIRED/ !-- 对select和get开头的方法应用只读事务提高查询效率 -- tx:method nameselect* read-onlytrue propagationSUPPORTS/ tx:method nameget* read-onlytrue propagationSUPPORTS/ /tx:attributes /tx:advice4.3、配置切点使用AOP的aop:pointcut标签定义哪些方法需要被事务管理。通常我们将切入点设置为业务层Service的所有方法aop:config aop:pointcut expressionexecution(* com.hg.service.*.*(..)) idpointcut/ /aop:config优势通过以上配置所有符合切入点表达式的业务方法都将自动获得事务管理。开发者只需关注核心业务逻辑事务的开启、提交、回滚等操作完全由Spring容器在后台通过动态代理自动完成实现了业务代码与非功能性需求事务的彻底解耦。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2420086.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!