当前位置: 首页 > news >正文

【JavaEE】Spring事务

目录

  • 一、事务简介
  • 二、Spring事务的实现
    • 2.1 事务的操作
    • 2.2 分类
      • 2.2.1 Spring编程式事务
      • 2.2.2 Spring 声明式事务 @Transactional
        • 2.2.2.1 @Transactional 详解
          • 2.2.2.1.1 rollbackFor
          • 2.2.2.1.2 Isolation
          • 2.2.2.1.3 propagation

一、事务简介

事务:事务是⼀组操作的集合,是⼀个不可分割的操作。事务会把所有的操作作为⼀个整体,⼀起操作。所以这组操作要么同时成功,要么同时失败。

二、Spring事务的实现

2.1 事务的操作

事务的操作主要有三步:

  1. 开启事start transaction / begin (⼀组操作前开启事务)
  2. 提交事务: commit (这组操作全部成功,提交事务)
  3. 回滚事务: rollback (这组操作中间任何⼀个操作出现异常,回滚事务)

2.2 分类

Spring 中的事务操作分为两类:

  1. 编程式事务(⼿动写代码操作事务)
  2. 声明式事务(利⽤注解⾃动开启和提交事务)

2.2.1 Spring编程式事务

SpringBoot 内置了两个对象:

  1. DataSourceTransactionManager 事务管理器。⽤来获取事务(开启事务),提交或回滚事务
  2. TransactionDefinition 是事务的属性,在获取事务的时候需要将 TransactionDefinition 传递进去从⽽获得⼀个事务 TransactionStatus

示例:

package com.example.springtransdemo.controller;import com.example.springtransdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/user")
@RestController
public class UserController {@Autowiredprivate UserService userService;//事务属性@Autowiredprivate TransactionDefinition definition;//事务管理器@Autowiredprivate DataSourceTransactionManager transactionManager;@RequestMapping("/registry")public String registry(String name,String password) {//开启事务TransactionStatus transaction = transactionManager.getTransaction(definition);//⽤⼾注册userService.registryUser(name, password);//提交事务transactionManager.commit(transaction);//回滚事务//transactionManager.rollback(transaction);return "注册成功";}
}

当我们不提交时可以在数据库中添加字段,回滚后就不会在数据库中添加字段,提交和回滚方法不能在同一个事务中调用。

2.2.2 Spring 声明式事务 @Transactional

使用这个注解需要添加依赖,但是如果已经添加了MyBatis的依赖,那么就包含了下面需要引入的依赖的内容。

<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId>
</dependency>

注解的应用,在需要使用到事务的方法上加上注解,就会自动提交事务状态。当发⽣了没有处理的error和RunTimeException异常(默认情况下)的时候,就会自动回滚。
例如上面的代码就可以改为:

        @RequestMapping("/registry")@Transactionalpublic String registry(String name,String password) {//⽤⼾注册userService.registryUser(name, password);return "注册成功";}

那么当我们就是要在捕获处理了异常后,还是将事务进行回滚时,我们就可以手动回滚使用TransactionAspectSupport类下使用currentTransactionStatus方法获取状态,使用isRollbackOnly方法回滚。

 @RequestMapping("/registry")@Transactionalpublic String registry(String name,String password) {//⽤⼾注册userService.registryUser(name, password);try{int a = 10 / 0;} catch (Exception e) {log.error("错误");TransactionAspectSupport.currentTransactionStatus().isRollbackOnly();}return "注册成功";}
2.2.2.1 @Transactional 详解

修饰范围:

  • 修饰类时,就是修饰类中的所用访问修饰限定符为public的方法。
  • 修饰方法时,只能修饰访问修饰限定符为public的方法。

@Transactiona 常见三大属性:

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

@Transactional 默认只在遇到运⾏时异常RunTimeException和Error时才会回滚。

例如执行下面的操作的时候,事务不会回滚,数据库中还是会添加数据。

        @RequestMapping("/registry")@Transactionalpublic String registry(String name,String password) throws IOException {//⽤⼾注册userService.registryUser(name, password);if(true) {throw new IOException();}return "注册成功";}

但是我们加上属性rollbackFor就会在发生rollbackFor指定的异常的时候回滚。

        @RequestMapping("/registry")@Transactional(rollbackFor = Exception.class)public String registry(String name,String password) throws IOException {//⽤⼾注册userService.registryUser(name, password);if(true) {throw new IOException();}return "注册成功";}

还有与rollbackFor相似作用的属性:

  • rollbackFor :使用class作为值,在发生该异常的时候回滚。
  • rollbackForClassName:使用类名作为值,在发生该异常的时候回滚。
  • noRollbackFor :使用class作为值,在发生该异常的时候不回滚。
  • noRollbackForClassName:使用类名作为值,在发生该异常的时候不回滚。

    当我们同时使用@Transactionsl的noRollbackFor和rollbackFor对同一异常类处理,后使用的会覆盖前面的。例如 @Transactional(rollbackFor = IOException.class, noRollbackFor = IOException.class)生效的是noRollbackFor = IOException.class
2.2.2.1.2 Isolation

Spring事务的隔离级别有以下几种值:

  • DEFAULT:数据库是什么隔离级别,这个方法就还是什么隔离级别。

剩下的都对应MySQL的隔离级别。

  1. 读未提交(READ_UNCOMMITTED):读未提交,也叫未提交读。该隔离级别的事务可以看到其他事务中
    未提交的数据,会有脏读问题。
  2. 读提交(READ_COMMITTED):读已提交,也叫提交读。该隔离级别的事务能读取到已经提交事务的数据,该隔离级别不会有脏读的问题。
  3. 可重复读(REPEATABLE_READ):事务不会读到其他事务对已有数据的修改,即使其他事务已提交。也就可以确保同⼀事务多次查询的结果⼀致,但是其他事务新插⼊的数据,是可以感知到的,这也就引发了幻读问题。
  4. 串⾏化(SERIALIZABLE):序列化,事务最⾼隔离级别。它会强制事务排序,使之不会发⽣冲突,从⽽解
    决了脏读,不可重复读和幻读问题,但因为执⾏效率低,所以真正使⽤的场景并不多。
2.2.2.1.3 propagation

事务的传播机制有以下七种。

我们以A方法调用B方法为例解释:

  1. Propagation.REQUIRED :默认的事务传播级别,如果当前存在事务,则加⼊该事务,如果当前没有事务,则创建⼀个新的事务。如果A方法有事务,B直接就加入,A没有事务B创建一个事务。
  2. Propagation.SUPPORTS :如果当前存在事务,则加⼊该事务。如果当前没有事务,则以⾮事务的⽅式继续运⾏。如果A方法有事务,B直接就加入,A没有事务B也没有事务。
  3. Propagation.MANDATORY :强制性。如果当前存在事务,则加⼊该事务。如果当前没有事务,则抛出异常。如果A方法有事务,B直接就加入,A没有事务抛异常。
  4. Propagation.REQUIRES_NEW :创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部⽅法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部⽅法都会新开启⾃⼰的事务,且开启的事务相互独⽴,互不⼲扰。如果A方法有事务,B创建一个事务,两个事务互不影响,A没有事务,B也会创建一个事务。
  5. Propagation.NOT_SUPPORTED :以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起(不⽤)。如果A方法有事务,B创建一个事务,使用B创建的事务,A没有事务B也没有。
  6. Propagation.NEVER :以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常。如果A方法有事务,抛异常,A没有事务B也没有。
  7. Propagation.NESTED :如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏。如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED 。如果A方法有事务,B创建一个事务,A的事务相当于B的父事务,A没有事务,B也会创建一个事务。
传播行为当前有事务当前无事务
REQUIRED加入事务新建事务
SUPPORTS加入事务非事务执行
MANDATORY加入事务抛出异常
REQUIRES_NEW挂起当前事务并新建事务新建事务
NOT_SUPPORTED挂起当前事务并以非事务执行非事务执行
NEVER抛出异常非事务执行
NESTED创建嵌套事务新建事务

相关文章:

  • 【JavaEE】-- 网络原理
  • 深度解析 torch.mean 的替代方案
  • Java消息队列应用:Kafka、RabbitMQ选择与优化
  • PyTorch 入门学习笔记
  • 记录一次session安装应用recyclerview更新数据的bug
  • Qt 的简单示例 -- 地址簿
  • 聊聊JVM怎么调优?(实战总结)
  • 单链表反序实现
  • 数据结构 - 树的遍历
  • 从零开始搞个简易分布式部署环境
  • 【大模型原理与技术-毛玉仁】第二章 大语言模型架构
  • LangChain快速入门:使用LangChain构建高效的并行语言处理链
  • 切换到旧提交,同时保证当前修改不丢失
  • WMS系统选型与实施避坑手册
  • android系统framework的几个新面试题目(涉及binder,input,SurfaceFlinger带答案)
  • 基于DFT码本的波束方向图生成MATLAB实现
  • Next.js 15 与 Apollo Client 的现代集成及性能优化
  • 低功耗双目云台监控设备采用国标控制装置
  • 【Java工程师面试全攻略】Day3:Java并发编程面试精要
  • 编译Ambari 3.0.0全攻略
  • 易支付做网站接口怎么赚钱/seo知识培训
  • 做购物网站用什么应用/最好用的系统优化软件
  • 下载站源码cms/网站seo排名优化价格
  • 淘宝联盟网站怎么做/郑州疫情最新情况
  • 生态农庄网站模板/制作网页设计公司
  • h5网站开发平台/行业网络营销