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 工作原理失效处理的主要内容,如果未能解决你的问题,请参考以下文章

全面分析 Spring 的编程式事务管理及声明式事务管理(转)

全面分析 Spring 的编程式事务管理及声明式事务管理

全面分析 Spring 的编程式事务管理及声明式事务管理

全面分析 Spring 的编程式事务管理及声明式事务管理

Spring 的编程式事务管理及声明式事务管理

全面分析 Spring 的编程式事务管理及声明式事务管理