Spring 事务处理

1.事务

事务 (Transaction)是数据库操作的最小工作单元,它是一个操作序列,这些操作要么全部执行成功 ,要么全部不执行(回滚到最初状态)

2.Spring编程式事务

Spring ⼿动操作事务和上⾯ MySQL 操作事务类似,有 3 个重要操作步骤:

  • 开启事务(获取事务)

  • 提交事务

  • 回滚事务

SpringBoot 内置了两个对象:

  1. DataSourceTransactionManager​ 事务管理器。⽤来获取事务(开启事务),提交或回滚事务

  2. TransactionDefinition​ 是事务的属性,在获取事务的时候需要将 TransactionDefinition 传递进去从⽽获得⼀个事务 TransactionStatus

复制代码
@Autowired//注入事务管理器
private DataSourceTransactionManager dataSourceTransactionManager;
@Autowired//注入事务配置
private TransactionDefinition transactionDefinition;
复制代码
//开启事务
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
复制代码
//提交事务
dataSourceTransactionManager.commit(transaction);
复制代码
//回滚事务
dataSourceTransactionManager.rollback(transaction);

3.Spring声明式事务

方法/类添加@Transactional,大体上有五种情况:

注:下面提到的异常都是运行时异常,还有其他异常情况不一样 ,在后续**@Transactional详解**中讲解

  • 代码正常运行:事务提交
  • 代码发生异常:事务回滚
  • 代码发生异常,捕获异常并处理:事务提交
  • 代码发生异常,捕获异常并抛出:事务回滚
  • 代码发生异常,不希望抛出异常并实现回滚:手动实现,**TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();**如下所示
复制代码
@RequestMapping("/trans")
@RestController
public class TransController {
    @Autowired
    private UserService userService;

   @Transactional
    @RequestMapping("/registry")
    public String registry(String name,String password){
        
        userService.registryUser(name,password);
        try {
            int a=10/0;
        }catch(Exception e){
            System.out.println("发生异常");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return "注册成功";
    }
}

4.@Transactional详解

@Transactional是 Spring 框架中用于声明式事务管理的关键注解。它简化了事务编程,通过简单的注解即可实现复杂的事务管理。它包含三种属性

  • rollbackFor: 异常回滚属性. 指定能够触发事务回滚的异常类型. 可以指定多个异常类型
  • Isolation: 事务的隔离级别. 默认值为 Isolation.DEFAULT
  • propagation: 事务的传播机制. 默认值为 Propagation.REQUIRED

(1)rollbackFor

默认只在Error 和抛出/发生运行时异常时发生事务回滚,其他类型不会发生回滚

因此在注解中可以进行设置如:**@Transactional(rollbackFor=Exception.class)**代表发生所有异常时都会回滚

(2)事务隔离级别

(2).1MySQL 事务隔离级别

  • 读未提交:a事务进行数据操作但未提交时,b事务能够读到a操作后的数据, 但是 因为a事务可能回滚,b事务读到的数据没有意义,存在脏读问题
  • 读已提交:解决脏读问题,a事务操作数据但未提交时,b事务无法读到a操作后的数据 但是 ,当a事务提交之后,b读到的数据和之前读到的数据不一样,存在不可重复读问题
  • **可重复读:解决不可重复读问题,b事务不会读到a事务对已有数据的修改,即使已经提交 (默认级别)**但是, 当b事务进行操作时能感知到a对数据进行过操作,存在幻读问题
  • 串行化: 对事务序列化,a事务全部执行完之后,才能进行b事务操作,解决上述全部问题, 但是效率低下

(2).2 Spring 事务隔离级别
Spring 中事务隔离级别有5 种:

  • Isolation.DEFAULT : 以连接的数据库的事务隔离级别为主.
  • Isolation.READ_UNCOMMITTED : 读未提交, 对应SQL标准中 READ UNCOMMITTED
  • Isolation.READ_COMMITTED : 读已提交,对应SQL标准中 READ COMMITTED
  • Isolation.REPEATABLE_READ : 可重复读, 对应SQL标准中 REPEATABLE READ
  • Isolation.SERIALIZABLE : 串⾏化, 对应SQL标准中 SERIALIZABLE

(3)事务传播机制

事务传播机制就是: 多个事务⽅法存在调⽤关系时, 事务是如何在这些⽅法间进⾏传播的.
@Transactional 注解⽀持事务传播机制的设置, 通过 propagation 属性来指定传播⾏为.
Spring 事务传播机制有以下 7 种:
假设a事务调用b事务

  • Propagation.REQUIRED : 默认的事务传播级别. 如果a有事务,则b使用a事务;如果a没有,则b创建事务
  • Propagation.SUPPORTS : 如果a有事务,则b使用a事务;如果a没有,则b以非事务方式进行
  • Propagation.MANDATORY :如果a有事务,则b使用a事务;如果a没有,则b抛出异常
  • Propagation.REQUIRES_NEW : 不管a有没有事务,b都开启新事务
  • Propagation.NOT_SUPPORTED : 不管a有没有事务,b都以非事务方式运行
  • Propagation.NEVER : 以非事务方式运行,如果a有事务,b直接抛异常
  • Propagation.NESTED : 如果当前a有事务, 则b创建⼀个事务作为当前事务的嵌套事务来运⾏.如果a没有事务, 则b创建事务
相关推荐
心静财富之门26 分钟前
Flask 详细讲解 + 实战实例(零基础可学)
后端·python·flask
大鸡腿同学7 小时前
【成长类】《只有偏执狂才能生存》读书笔记:程序员的偏执型成长地图
后端
0xDevNull8 小时前
MySQL数据冷热分离详解
后端·mysql
一定要AK8 小时前
Spring 入门核心笔记
java·笔记·spring
A__tao8 小时前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
AI袋鼠帝8 小时前
OpenClaw(龙虾)最强开源对手!Github 40K Star了,又一个爆火的Agent..
后端
KevinCyao8 小时前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
凯尔萨厮8 小时前
创建SpringWeb项目(Spring2.0)
spring·mvc·mybatis
迷藏4948 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
wuxinyan1239 小时前
Java面试题47:一文深入了解Nginx
java·nginx·面试题