spring事务详解(二)简单样例

系列目录

spring事务详解(一)初探事务html

spring事务详解(二)简单样例spring

spring事务详解(三)源码详解数据库

spring事务详解(四)测试验证编程

spring事务详解(五)总结提升ide

1、引子

在Spring中,事务有两种实现方式:测试

  1. 编程式事务管理: 编程式事务管理使用底层源码可实现更细粒度的事务控制。spring推荐使用TransactionTemplate,典型的模板模式。
  2. 申明式事务管理: 添加@Transactional注解,并定义传播机制+回滚策略。基于Spring AOP实现,本质是对方法先后进行拦截,而后在目标方法开始以前建立或者加入一个事务,在执行完目标方法以后根据执行状况提交或者回滚事务。

2、简单样例

需求:

建立用户时,新建一个用户余额表。若是用户余额建立失败抛出异常,那么用户表也回滚,即要保证“新增用户+新增用户余额”一块儿成功 或 回滚。this

2.1 申明式事务管理

以下图,只须要在service.impl层,业务方法上添加@Transactional注解,定义事务的传播机制为REQUIRED(不写这个参数,默认就是REQUIRED),遇到Exception异常就一块儿回滚。spa

REQUIRED传播机制下:存在加入事务,不存在建立新事务。保证了当前方法中的全部数据库操做都在一个物理事务中,当遇到异常时会整个业务方法一块儿回滚。code

 1 /**
 2      * 建立用户并建立帐户余额
 3      *
 4      * @param name
 5      * @param balance
 6      * @return
 7      */
 8     @Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
 9     @Override
10     public void addUserBalanceAndUser(String name, BigDecimal balance) {
11         log.info("[addUserBalanceAndUser] begin!!!");
12         //1.新增用户
13         userService.addUser(name);
14         //2.新增用户余额
15         UserBalance userBalance = new UserBalance();
16         userBalance.setName(name);
17         userBalance.setBalance(new BigDecimal(1000));
18         this.addUserBalance(userBalance);
19         log.info("[addUserBalanceAndUser] end!!!");
20     }

 

2.2 编程式事务管理

编程式事务管理,咱们使用Spring推荐的transactionTemplate。我这里由于使用的是spring cloud的注解配置,实现用了自动配置类配置好了TransactionTemplate这个类型的bean.使用的时候直接注入bean使用便可(固然老式的xml配置也是同样的)。以下:xml

 1 /**
 2      * 建立用户并建立帐户余额(手动事务,不带结果)
 3      *
 4      * @param name
 5      * @param balance
 6      * @return
 7      */
 8     @Override
 9     public void addUserBalanceAndUserWithinTT(String name, BigDecimal balance) {
10         //实现一个没有返回值的事务回调
11         transactionTemplate.execute(new TransactionCallbackWithoutResult() {
12             @Override
13             protected void doInTransactionWithoutResult(TransactionStatus status) {
14                 try {
15                     log.info("[addUserBalanceAndUser] begin!!!");
16 
17                     //1.新增用户
18                     userService.addUser(name);
19                     //2.新增用户余额
20                     UserBalance userBalance = new UserBalance();
21                     userBalance.setName(name);
22                     userBalance.setBalance(new BigDecimal(1000));
23                     userBalanceRepository.insert(userBalance);
24                     log.info("[addUserBalanceAndUser] end!!!");
25                     //注意:这里catch住异常后,设置setRollbackOnly,不然事务不会滚。固然若是不须要自行处理异常,就不要catch了
26                 } catch (Exception e) {
27                     // 异常回滚
28                     status.setRollbackOnly();
29                     log.error("异常回滚!,e={}",e);
30                 }
31 
32             }
33         });
34     }

注意:

1.能够不用try catch,transactionTemplate.execute本身会捕捉异常并回滚。--》推荐

2.若是有业务异常须要特殊处理,记得:status.setRollbackOnly(); 标识为回滚。--》特殊状况才使用

3、总结

spring支持的这两种方式均可以,我的认为大部分状况下@Transactional能够知足须要。

相关文章
相关标签/搜索