Spring事务和事务传播机制(@Transactional)

文章目录

  • Spring事务(@Transactional详解)
    • 什么是事务
      • 为什么需要事务
      • 事务的操作(sql)
    • Spring中的事务实现
    • Spring编程式事务
    • Spring声明式事务 @Transactional
      • @Transactional可以用来修饰方法或类
      • 对异常进行捕获细节:
    • @Transactional详解
      • 三个属性
        • 1. rooback
        • 2. Isolation
          • 事务的隔离级别:
            • MySQL事务隔离级别
            • Spring事务隔离级别
        • 3. propagation
          • 什么是事务传播机制
          • 传播机制有哪些

Spring事务(@Transactional详解)

什么是事务

为什么需要事务

转账操作:
第一步:A账户 -100元
第二步:B账户 +100元

如果没有事务,第一步执行成功了,第二步执行失败了,那么A账户的100元就平白无故的消失了.

秒杀系统
第一步:下单成功
第二步:扣减库存

下单成功后,库存要么同步减少,要么扣减失败,所以得把这两个操作放在同一个事务中,要么一起成功,要么一起失败

事务的操作(sql)

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

--提交事务
commit;

--回滚事务
rollback;

Spring中的事务实现

  • 编程式事务(手动写代码操作事务)
  • 声明式事务(通过注解自动开启和提交事务)

Spring编程式事务

1.在controller 层 @Autowired 注入事务管理器
2.开启事务
3.提交事务

package com.example.mybatisdemo.controller;

import com.example.mybatisdemo.model.User;
import com.example.mybatisdemo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
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;

/**
 * 手动提交事务
 */
@Slf4j
@RequestMapping("/trans")
@RestController
public class TransactionController {

    @Autowired
    private UserService userService;

    //获取数据库事务管理器
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    //数据库事务默认配置
    @Autowired
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/addUser")
    public Integer addUser(String username,String password){
        //获取一个事务
        TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
        User user=new User(username,password);
        Integer result = userService.insert(user);
        log.info("影响行数:"+result);
        //回滚到transaction状态
        //dataSourceTransactionManager.rollback(transaction);
        //事务提交
        dataSourceTransactionManager.commit(transaction);
        return  result;
    }
}



 

Spring声明式事务 @Transactional

@Transactional可以用来修饰方法或类

  • 修饰方法时:只有修饰public方法时才生效,修饰其他方法时不会报错,也不生效

  • 修饰类时:对改类的所以public修饰的方法都生效
    执行流程 :被@Transactional修饰时,在目标方法开始执行之前,会自动开启事务,方法执行结束之后,自动提交事务。
    如果在方法执行过程中,出现异常,而且异常未被捕获,就会进行回滚操作
    如果异常被程序捕获,方法就被认为是执行成功,依然会提交事务

    请添加图片描述

对异常进行捕获细节:

@Transactional
@RequestMapping("/registry")
public String registry(String name,String password){
 //⽤⼾注册
 	userService.registryUser(name,password);
 	log.info("⽤⼾数据插⼊成功");
 //对异常进⾏捕获
 	try {
 //制造程序抛出异常
 	int a = 10/0;
 }catch (Exception e){
	 e.printStackTrace();
 }
 	return "注册成功";
}

上述例子,因为程序被捕获了,所以事务依然可以提交

如果需要事务进行回滚:

  1. 重新抛出异常
@Transactional
@RequestMapping("/registry")
public String registry(String name,String password){
 //⽤⼾注册
 	userService.registryUser(name,password);
 	log.info("⽤⼾数据插⼊成功");
 //对异常进⾏捕获
 	try {
 //制造程序抛出异常
 	int a = 10/0;
 }catch (Exception e){
	 //将异常重新抛出去
	 throw e;
 }
 	return "注册成功";
}
  1. 手动回滚事务
@Transactional
@RequestMapping("/registry")
public String registry(String name,String password){
 //⽤⼾注册
 	userService.registryUser(name,password);
 	log.info("⽤⼾数据插⼊成功");
 //对异常进⾏捕获
 	try {
 //制造程序抛出异常
 	int a = 10/0;
 }catch (Exception e){
 //手动回滚事务
	  TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
 }
 	return "注册成功";
}

@Transactional详解

三个属性

1. rooback

异常回滚属性.指定能够触发事务回滚的异常类型。可以指定多个异常
在这里插入图片描述
@Transactional 只有运行时异常和Error才能进行回滚

需要所有异常都回滚, 需要来配置 @Transactional 注解当中的 rollbackFor 属性, 通
过 rollbackFor 这个属性指定出现何种异常类型时事务进⾏回滚

Transactional(rollbackFor = Exception.class)
@RequestMapping("/r2")
public String r2(String name,String password) throws IOException {
 //⽤⼾注册
     userService.registryUser(name,password);
     log.info("⽤⼾数据插⼊成功");
     if (true){
 		throw new IOException();
  }
   return "r2";
  }
2. Isolation
事务的隔离级别:
MySQL事务隔离级别
  1. 读未提交(READ UNCOMMITTED): 读未提交, 也叫未提交读. 该隔离级别的事务可以看到其他事务中
    未提交的数据.
    因为其他事务未提交的数据可能会发⽣回滚, 但是该隔离级别却可以读到, 我们把该级别读到的数
    据称之为脏数据, 这个问题称之为脏读.
  2. 读提交(READ COMMITTED): 读已提交, 也叫提交读. 该隔离级别的事务能读取到已经提交事务的数
    据,
    该隔离级别不会有脏读的问题.但由于在事务的执⾏中可以读取到其他事务提交的结果, 所以在不
    同时间的相同 SQL 查询可能会得到不同的结果, 这种现象叫做不可重复读
  3. 可重复读(REPEATABLE READ): 事务不会读到其他事务对已有数据的修改, 即使其他事务已提交. 也
    就可以确保同⼀事务多次查询的结果⼀致, 但是其他事务新插⼊的数据, 是可以感知到的. 这也就引
    发了幻读问题. 可重复读, 是 MySQL 的默认事务隔离级别.
    ⽐如此级别的事务正在执⾏时, 另⼀个事务成功的插⼊了某条数据, 但因为它每次查询的结果都是
    ⼀样的, 所以会导致查询不到这条数据, ⾃⼰重复插⼊时⼜失败(因为唯⼀约束的原因). 明明在事务
    中查询不到这条信息,但⾃⼰就是插⼊不进去,这个现象叫幻读
  4. 串⾏化(SERIALIZABLE): 序列化, 事务最⾼隔离级别. 它会强制事务排序, 使之不会发⽣冲突, 从⽽解
    决了脏读, 不可重复读和幻读问题, 但因为执⾏效率低, 所以真正使⽤的场景并不多.
Spring事务隔离级别

Spring 中事务隔离级别有5 种:

  1. Isolation.DEFAULT : 以连接的数据库的事务隔离级别为主.
  2. Isolation.READ_UNCOMMITTED : 读未提交, 对应SQL标准中 READ UNCOMMITTED
  3. Isolation.READ_COMMITTED : 读已提交,对应SQL标准中 READ COMMITTED
  4. Isolation.REPEATABLE_READ : 可重复读, 对应SQL标准中 REPEATABLE READ
  5. Isolation.SERIALIZABLE : 串⾏化, 对应SQL标准中 SERIALIZABLE
Transactional(isolation = Isolation.READ_COMMITTED)
@RequestMapping("/r3")
public String r3(String name,String password) throws IOException {
 //... 代码省略
 return "r3";
}
3. propagation

事务的传播机制

什么是事务传播机制

事务传播机制就是:多个事务方法存在调用关系时,事务是如何在这些方法间进行传播的。

比如两个方法A,B都被@Transactional修饰

  • A方法运行时,开启一个事务,当A调用B时,B方法本身也有事务
  • 此时B方法运行时,是加入A的事务,还是创建一个新的事务呢?
    这就设计到事务的传播机制
传播机制有哪些

Transactional 注解⽀持事务传播机制的设置, 通过 propagation 属性来指定传播⾏为.
Spring 事务传播机制有以下 7 种:

  1. Propagation.REQUIRED : 默认的事务传播级别. 如果当前存在事务, 则加⼊该事务. 如果当前没
    有事务, 则创建⼀个新的事务.
  2. Propagation.SUPPORTS : 如果当前存在事务, 则加⼊该事务. 如果当前没有事务, 则以⾮事务的
    ⽅式继续运⾏.
  3. Propagation.MANDATORY :强制性. 如果当前存在事务, 则加⼊该事务. 如果当前没有事务, 则
    抛出异常.
  4. Propagation.REQUIRES_NEW : 创建⼀个新的事务. 如果当前存在事务, 则把当前事务挂起. 也
    就是说不管外部⽅法是否开启事务, Propagation.REQUIRES_NEW 修饰的内部⽅法都会新开
    启⾃⼰的事务, 且开启的事务相互独⽴, 互不⼲扰.
  5. Propagation.NOT_SUPPORTED : 以⾮事务⽅式运⾏, 如果当前存在事务, 则把当前事务挂起(不
    ⽤).
  6. Propagation.NEVER : 以⾮事务⽅式运⾏, 如果当前存在事务, 则抛出异常.

比如⼀对新⼈要结婚了, 关于是否需要房⼦

  1. Propagation.REQUIRED : 需要有房⼦. 如果你有房, 我们就⼀起住, 如果你没房, 我们就⼀起
    买房. (如果当前存在事务, 则加⼊该事务. 如果当前没有事务, 则创建⼀个新的事务)
  2. Propagation.SUPPORTS : 可以有房⼦. 如果你有房, 那就⼀起住. 如果没房, 那就租房. (如果
    当前存在事务, 则加⼊该事务. 如果当前没有事务, 则以⾮事务的⽅式继续运⾏)
  3. Propagation.MANDATORY : 必须有房⼦. 要求必须有房, 如果没房就不结婚. (如果当前存在事
    务, 则加⼊该事务. 如果当前没有事务, 则抛出异常)
  4. Propagation.REQUIRES_NEW : 必须买新房. 不管你有没有房, 必须要两个⼈⼀起买房. 即使
    有房也不住. (创建⼀个新的事务. 如果当前存在事务, 则把当前事务挂起)
  5. Propagation.NOT_SUPPORTED : 不需要房. 不管你有没有房, 我都不住, 必须租房.(以⾮事务
    ⽅式运⾏, 如果当前存在事务, 则把当前事务挂起)
  6. Propagation.NEVER : 不能有房⼦. (以⾮事务⽅式运⾏, 如果当前存在事务, 则抛出异常)
  7. Propagation.NESTED : 如果你没房, 就⼀起买房. 如果你有房, 我们就以房⼦为根据地,做点下
    ⽣意. (如果如果当前存在事务, 则创建⼀个事务作为当前事务的嵌套事务来运⾏. 如果当前没有事
    务, 则该取值等价于 PROPAGATION_REQUIRED )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/624528.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

牛客NC363 开锁【中等 BFS Java/Go/PHP】

题目 题目链接: https://www.nowcoder.com/practice/e7cbabbf7e0a41ec98055ee5f3d33bbe https://www.lintcode.com/problem/796 思路 Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改&#x…

在PyQt5中实现点击按钮打开新窗口功能—窗口的跳转功能实现

百度搜索“pyqt5中如何点击按钮打开新的窗口”,自动生成以下参考代码。 在PyQt5中,要实现点击按钮打开新窗口,你需要定义一个新的窗口类,并在按钮的点击信号(clicked)处理函数中创建并显示这个新窗口。以下…

Eclipse 里如何建立SAP应用服务层的CDS

关于Core Data Service(CDS) CDS:Core Data Ser vice.核心数据服务。CDS 是使用基于 SQL的数据定义语言(DDL)定义的,该语言基于标准 SQL 并带有一些附加概念。使用类似 SQL的灵活表达式可以进行复杂的数据建模。有两种类型的 CDS:ABAP CDS 和 HANA CDS。 S/4 HANA…

安装HTTPS证书后,网站安全性会有哪些提升?

在当今数字化时代,网络安全已成为一个不可忽视的话题。随着网络攻击的日益频繁,保护网站和用户数据的安全变得尤为重要。HTTPS作为一种加密的HTTP协议,为我们提供了一种安全的网络数据传输方式。本文将详细介绍HTTPS的工作原理、端口号以及如…

测试docker GPU性能损失

NVIDIA 3090 利用HSOpticalFlow代码测试docker GPU性能损失 docker介绍图如下: 形象生动展示了他们之间的关系 今天要测试docker容器运行HSOpticalFlow算法的性能损失,包括CPU和GPU 上一篇博客 http://t.csdnimg.cn/YW5kE 我已经介绍了使用docker和nvid…

如何判断海外住宅ip的好坏?

在海外IP代理中,住宅IP属于相对较好的资源,无论是用于工作、学习、还是娱乐,都能得到较好的使用效果。作为用户,该如何判断海外住宅IP的好坏呢? 稳定性与可靠性:海外住宅IP相比动态IP地址,通常具…

国际数字影像产业园近期活动一览

一、4月23日,在数媒大厦的春日里,我们共同迎来了第29个“世界读书日"。由数字影像联合工会委员会、树莓科技(成都)集团有限公司工会委员会主办,成都树莓信息技术有限公司、四川聚能文化传播公司承办的「共沐书香 …

“AI换脸”“一键脱衣” AI诈骗正在进行

这两年AI技术快速发展,从AI变声到AI换脸,AI技术在给我们带来震撼的同时,也有心术不正的人利用它做坏事。比如,近来媒体常报道的“一键脱衣”案件,一位广州女生在地铁拍的美照,被个别网友,用AI一…

(值得拥有)项目框架构建之7:提供工业互联网的框架基础,本文附带框架基础源码

很多读者,可能只是匆匆一看,感觉没啥东西。 但我要特意提醒各位读者:此源码,可是非常有价值的东西。我不一定会一直开放。 前述文章曾讲解了大概如何构建一个项目框架,本意是好的,无奈框架这种思想性的东西…

react18【系列实用教程】组件 (2024最新版 | 含父子组件传值、兄弟组件传值、越层组件传值、“插槽“)

什么是组件? 一个组件就是用户界面的一部分,它可以有自己的逻辑和外观。 组件之间可以互相嵌套,也可以复用多次 为什么要用组件? 组件能让开发者像搭积木一样快速构建一个完整的庞大应用,大大提升了开发效率&#xff…

【MySQL数据库】丨高可用之MHA集群部署

一、准备工作 1.1 修改主机名 vim /etc/hosts# 添加对应主机 192.168.28.128 mha1 192.168.28.131 mha2 192.168.28.132 mha31.2 关闭防火墙及修改selinux # 关闭防火墙 systemctl stop firewalld systemctl disable firewalld # 关闭自启动# 修改selinux vim /etc/sy…

EasyImage2.0 图床源码

EasyImage2.0 是一个简单图床的源码,它支持以下功能: 1. API接口 2. 登录后才能上传图片 3. 设置图片质量 4. 压缩图片大小 5. 添加文字或图片水印 6. 设定图片的宽度和高度 7. 将上传的图片转换为指定的格式 8. 限制上传图片的最小宽度和高度 …

基于STC12C5A60S2系列1T 8051单片机实现一主单片机发送数据给一从单片机接收并返回数据给主单片机的串口通信功能

基于STC12C5A60S2系列1T 8051单片机实现一主单片机发送数据给一从单片机接收并返回数据给主单片机的串口通信功能 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机串口通信介绍STC12C5A60S2系列1T 8051单片机串口通信的结构基于STC12C5A60S2系列1T 8051单片…

langchain_community切分各种文档数据;加载向量模型;使用向量库

参考: https://github.com/langchain-ai/langchain https://api.python.langchain.com/en/latest/community_api_reference.html https://github.com/shibing624/ChatPilot/blob/384f18e4f10f87e10f104f9ff57f02c655588035/chatpilot/apps/rag_app.py 安装: pip instal…

# 从浅入深 学习 SpringCloud 微服务架构(十八)

从浅入深 学习 SpringCloud 微服务架构(十八) 一、开源配置中心 Apollo:概述 1、开源配置中心 Apollo Apollo -A reliable configuration management system Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理…

Gitlab、Redis、Nacos、Apache Shiro、Gitlab、weblogic相关漏洞

文章目录 一、Gitlab远程代码执行(CVE-2021-22205)二、Redis主从复制远程命令执行三、Nacos认证绕过漏洞(CVE-2021-29441)四、Apache Shiro认证绕过漏洞(CVE-2020-1957)五、Gitlab任意文件读取漏洞&#xf…

北亚MF2200手机取证平台介绍

一、产品介绍。 北亚MF2200手机取证平台是由北亚企安科技(北京)有限公司(Frombyte)自主研发的一款针对智能手机(iPhone、Android)及 iPad 取证分析的法证平台。本平台采集速度快,可通过自动提取…

如何选择沙发3D模型下载?

在家具沙发定制过程中,选择合适的沙发3D模型可以方便地进行沟通,让双方能够更清晰地了解对方的设想。此外,通过3D模型,双方还可以更方便地对设计方案进行修改和完善。那么如何选择合适的沙发3D模型下载? 1.确定预算 在选择沙发3D…

一篇文章告诉你:通信网优比计算机岗位好在哪?

据优橙2023年就业人员专业分布统计,通信专业学员占比32.7%,非通信专业学员占比64.8%,其他占比2.5%。 可见从事网优的学员中大部分为非通信专业。而非通信专业中72%的学生在学习通信网优还是计算机专业中,选择了通信网优。 为什么越…

C# WinForm —— 14 CheckedListBox 复选列表框介绍

1. 简介 类似 ListBox,提供项的列表,区别就是 CheckedListBox 每一个项前面有个复选框 2. 常用属性 属性解释(Name)控件ID,在代码里引用的时候会用到,一般以 ckl 开头BackColor背景颜色BoderStyle边框样式:无、FixedSingle、F…