spring事务详解(二)简单样例spring
在Spring中,事务有两种实现方式:测试
建立用户时,新建一个用户余额表。若是用户余额建立失败抛出异常,那么用户表也回滚,即要保证“新增用户+新增用户余额”一块儿成功 或 回滚。this
以下图,只须要在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 }
编程式事务管理,咱们使用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(); 标识为回滚。--》特殊状况才使用
spring支持的这两种方式均可以,我的认为大部分状况下@Transactional能够知足须要。