SpringBoot事务的使用(编程式声明式)及 @Transactional 工作原理失效处理
Posted Perceus
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot事务的使用(编程式声明式)及 @Transactional 工作原理失效处理相关的知识,希望对你有一定的参考价值。
@TOC
回顾 事务
Spring 中事务的实现
Spring 中的事务操作分为两类:
在开始讲解它们之前,咱们先来回顾事务在 mysql 中是如何使⽤的?
MySQL 中的事务使⽤(回顾)
事务在 MySQL 有 3 个重要的操作:
它们对应的操作命令如下:
-- 开启事务
start transaction;
-- 业务执⾏
-- 提交事务
commit;
-- 回滚事务
rollback;
Spring 编程式事务(手动操作)
Spring ⼿动操作事务和上⾯ MySQL 操作事务类似,它也是有 3 个重要操作步骤:
SpringBoot 内置了两个对象:
实现代码如下:
@RestController
public class UserController
@Resource
private UserService userService;
// 注入 JDBC 事务管理器
@Resource
private DataSourceTransactionManager dataSourceTransactionManager;
// 注入 定义事务属性
@Resource
private TransactionDefinition transactionDefinition;
@RequestMapping("/sava")
public Object save(User user)
// 开启事务
TransactionStatus transactionStatus =
dataSourceTransactionManager
.getTransaction(transactionDefinition);
// 插⼊数据库
int result = userService.save(user);
// 提交事务
dataSourceTransactionManager.commit(transactionStatus);
// 回滚事务
dataSourceTransactionManager.rollback(transactionStatus);
return result;
从上述代码可以看出,以上代码虽然可以实现事务,但操作也很繁琐,有没有更简单的实现⽅法
呢?请 看下⾯声明式事务
。
Spring 声明式事务(自动事务)
具体实现代码如下:
@RequestMapping("/save")
@Transactional //开启事务
public Object save(User user)
int result = userService.save(user);
return result;
接下⾥使⽤以下代码,分别设置 @Transactional 注解和不设置 @Transactional
观察它们的执⾏区别:
@Transactional 作⽤范围
@Transactional 可以⽤来修饰⽅法或类:
@Transactional 参数说明
注意事项
验证以下代码是否会发⽣事务回滚:
@RestController
public class UserController
@Resource
private UserService userService;
@RequestMapping("/save")
@Transactional
public Object save(User user)
// 插⼊数据库
int result = userService.save(user);
try
// 执⾏了异常代码(0不能做除数)
int i = 10 / 0;
catch (Exception e)
System.out.println(e.getMessage());
return result;
事务不会自动回滚解决⽅案
解决⽅案1:将捕获异常重新抛出
因此解决⽅案1就是可以将异常重新抛出
,具体实 现如下:
@RequestMapping("/save")
@Transactional(isolation = Isolation.SERIALIZABLE)
public Object save(User user)
// 插⼊数据库
int result = userService.save(user);
try
// 执⾏了异常代码(0不能做除数)
int i = 10 / 0;
catch (Exception e)
System.out.println(e.getMessage());
throw e; // 将异常重新抛出去
return result;
解决⽅案2:手动回滚事务
具体实现代码如下:
@RequestMapping("/save")
@Transactional(isolation = Isolation.SERIALIZABLE)
public Object save(User user)
// 插⼊数据库
int result = userService.save(user);
try
// 执⾏了异常代码(0不能做除数)
int i = 10 / 0;
catch (Exception e)
System.out.println(e.getMessage());
// ⼿动回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return result;
@Transactional ⼯作原理
@Transactional 在开始执⾏业务之前,通过代理先开启事务,在执⾏成功之后再提交事务。如果中途遇 到的异常,则回滚事务。
@Transactional 实现思路预览:
@Transactional 具体执⾏细节如下图所示:
以上是关于SpringBoot事务的使用(编程式声明式)及 @Transactional 工作原理失效处理的主要内容,如果未能解决你的问题,请参考以下文章