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

Spring之事务实现方式及原理

目录

Spring事务简介

Spring支持事务管理的两种方式

编程式事务控制

声明式事务管理

Spring事务角色 

未开启事务之前

开启Spring的事务管理后

事务配置

事务传播行为

        事务传播行为的可选值


Spring事务简介

事务作用:在数据层保障一系列的数据库操作同成功同失败

Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败

需要注意的是:

程序是否支持事务首先取决与数据库,比如使用MySQL的,且选择的是innodb引擎,那么是可以支持事务的。但是,如果选择的是myisam引擎的话,那么从根本上就是不支持事务的,即使Spring中设置了事务,也不会生效。

Spring支持事务管理的两种方式

编程式事务控制

在源代码中编辑事务的逻辑流程,也就是在代码中设置动态信息,开启事务,提交事务,回滚事务

编程式事务控制通过TransationTemplate或者TransactionManager手动管理事务

声明式事务管理

实际是通过AOP实现,且基于@Transactional的全注解的方式也是使用最多的

使用声明式事务官的实现步骤:

步骤一:在需要被事务管理的方法上添加注解

@Transactional可以写在接口类上、接口方法上、实现类上和实现类方法上

  • 写在接口类上,该接口的所有实现类的所有方法都会有事务

  • 写在接口方法上,该接口的所有实现类的该方法都会有事务

  • 写在实现类上,该类中的所有方法都会有事务

  • 写在实现类方法上,该方法上有事务

  • 建议写在实现类或实现类的方法上

步骤二:在jdbcConfig类中配置事务管理器

//配置事务管理器,mybatis使用的是jdbc事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();transactionManager.setDataSource(dataSource);return transactionManager;
}

注意:事务管理器要根据使用技术进行选择,Mybatis框架使用的是JDBC事务,可以直接使用DataSourceTransactionManager  

步骤三:开启事务注解

在SpringConfig的配置类中开启

@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class
//开启注解式事务驱动
@EnableTransactionManagement
public class SpringConfig {
}

 设置好后运行测试类,就可以发现当业务出现错误后,事务就可以控制回滚,保证数据的正确性

Spring事务角色 

未开启事务之前

  • AccountDao 的outMoney因为是修改操作,会开启一个事务T1
  • AccountDao 的inMoney因为是修改操作,会开启一个事务T2
  • AccountService的transfer没有事务

执行后如果运行过程中没有抛异常,则T1heT2都正常提交,数据正确

如果两个方法中出现异常,T1执行成功提交事务,但T2因为抛异常不会执行,则就导致数据出现错误

开启Spring的事务管理后

  • transfer上添加了@Transactional注解,在该方法上就会有一个事务T

  • AccountDao的outMoney方法的事务T1加入到transfer的事务T中

  • AccountDao的inMoney方法的事务T2加入到transfer的事务T中

  • 这样就保证他们在同一个事务中,当业务层中出现异常,整个事务就会回滚,保证数据的准确性。

由上述可知:

  • 事务管理员:发起事务方,在Spring中通常指代业务层开启事务方法
  • 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法

注意:目前的事务管理是基于DataSourceTransactionManagerSqlSessionFactoryBean使用的是同一个数据源。

事务配置

以上这些属性都可以在@Transactional注解的参数上进行设置

  • readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true。

  • timeout:设置超时时间单位秒,在多长时间之内事务没有提交成功就自动回滚,-1表示不设置超时时间。

  • rollbackFor:当出现指定异常进行事务回滚

  • noRollbackFor:当出现指定异常不进行事务回滚

并不是所有的异常都会回滚事务,所以需要rolbackFor的存在,比如下列代码:

@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;@Transactionalpublic void transfer(String out,String in ,Double money) throws IOException{accountDao.outMoney(out,money);//int i = 1/0; //这个异常事务会回滚if(true){throw new IOException(); //这个异常事务就不会回滚}accountDao.inMoney(in,money);}

上述代码中不会出现回滚的的原因是:

Spring的事务只会对Error异常和RuntimeException异常及其子类进行事务回滚,其他的异常类型是不会回滚的,对应IOException不符合以上的条件,所以不回滚

此时就可以使用rollabckFor属性来设置出现IOException异常不回滚

 @Transactional(rollbackFor = {IOException.class})

此时 throw new IOException(); 这个异常事务就不会回滚

@Transactional的常用配置参数

属性名说明
propagation事务的传播行为,默认值为 REQUIRED
isolation事务的隔离级别,默认值采用 DEFAULT,可选的值
  • DEFAULT :默认隔离级别, 会采用数据库的隔离级别

  • READ_UNCOMMITTED : 读未提交

  • READ_COMMITTED : 读已提交

  • REPEATABLE_READ : 重复读取

  • SERIALIZABLE: 串行化

timeout事务的超时时间,默认值为-1(不会超时)。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly指定事务是否为只读事务,默认值为 false。true只读事务,false读写事务,增删改要设为false,查询设为true。
rollbackFor用于指定能够触发事务回滚的异常类型,并且可以指定多个异常类型。
noRollbackFor事务的传播行为,默认值为 REQUIRED,可选的值在上面介绍过

事务传播行为

加入一个记录日志的功能,事务T2也会加入到事务T中(因为事务传播行为的默认值为REQUIRED,所以此时虽然有@Transaction开启了事务T2还是会加入到事务T中)

若此时转账失败,所有事务回滚,导致日志中没有任何关于此次转账的信息,这显然是不行的;

此时,需修改logService改变事务的传播行为,通过@Transaction中的可选属性进行配置:

@Autowired
private LogDao logDao;
//propagation设置事务属性:传播行为设置为当前操作需要新事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void log(String out,String in,Double money ) {logDao.log("转账操作由"+out+"到"+in+",金额:"+money);
}

事务传播行为的可选值

 

相关文章:

Spring之事务实现方式及原理

目录 Spring事务简介 Spring支持事务管理的两种方式 编程式事务控制 声明式事务管理 Spring事务角色 未开启事务之前 开启Spring的事务管理后 事务配置 事务传播行为 事务传播行为的可选值 Spring事务简介 事务作用:在数据层保障一系列的数据库操作同成功…...

为独立服务器增加安全性的简单步骤

为独立服务器增加安全性的简单步骤 马上注册成为ROSABC会员,随时发帖回复。 您需要 登录 才可以下载或查看,没有账号?会员注册 x 独立服务器是您业务的中心,它需要尽可能的安全。对企业中心的攻击可能会导致您失去知识产权&…...

JavaScript--Cookie

什么是 Cookie? 在JavaScript中,cookie是一种小型的文本文件,它存储在用户的计算机上。通过使用cookie,网站可以向用户的浏览器发送数据,并将该数据保留在浏览器中,使网站能够在不同页面之间传递数据或存储…...

【单片机】晨启科技,酷黑版,简易电压采集装置

简易电压采集装置(限MSP430、STM32单片机) 任务要求: 设计制作一个简易电压采集与显示装置,实现如下基本功能: 评分细则: 1.通过单片机内部ADC模块采集1路电压并通过OLED屏显示电压大小;&#x…...

任务12、Quality指令加持,Midjourney生成电影级数码作品

12.1 任务概述 本次实验任务旨在帮助你掌握Midjourney AI绘画中的Quality指令。通过深入介绍Quality指令的概念和作用,我们将解释为什么它在绘画中至关重要。通过测试不同的Quality参数对绘画效果的影响,并提供实战演示,你将学会如何在Midjourney中设置Quality参数以达到更…...

第4章 字符串和格式化输入/输出

本章介绍以下内容: 函数:strlen() 关键字:const 字符串 如何创建、存储字符串 如何使用strlen()函数获取字符串的长度 用C预处理器指令#define和ANSIC的const修饰符创建符号常量 本章重点介绍输入和输出。与程序交互和使用字符串可以编写个性…...

嵌入式开发学习(STC51-7-矩阵按键)

内容 按下S1-S16键,对应数码管最左边显示0-F 矩阵按键简介 独立按键与单片机连接时,每一个按键都需要单片机的一个I/O 口,若某单片机系统需较多按键,如果用独立按键便会占用过多的I/O口资源;而单片机 系统中I/O口资…...

WMS仓储管理系统的价值从哪些方面体现

仓库管理在不断改善,采用信息化来管理仓库。自从使用了WMS仓储管理系统解决方案后,仓库管理的效率大大提高了,而且WMS系统有很多价值。 首先,WMS系统可以帮助员工更省时省力地完成仓库管理工作,提高效率和准确性。传统…...

网站推荐第二期-沉浸式网页翻译

通过在浏览器上安装插件形式实现,接入多方翻译接口,实现全平台翻译功能,甚至可以使用openai的chatgpt,效率倍增。 不仅可以双语阅读网页,甚至pdf也支持翻译。 推荐网址如下: 双语网页翻译 - 电子书翻译 …...

【独立后台】快递小程序便宜寄快递系统小程序 对接易达

快递代发项目简介: 顾名思义就是帮发快递。原本产业链是客户-快递之间的联系,现在变成了客户-我们-快递,简单来说就是我们把客户聚集到一起团购到了更优惠的价格。很简单就是赚一个差价, 单子多就能和各个快递合作的平台&#x…...

【JVM】垃圾回收 ——自问自答2

Q: System.gc() 的理解 System.gc()底层调用的是 Runtime.getRuntime.gc(),会现实出发FullGC。 但是,它的调用附带一个免责声明,无法保证对垃圾收集器的调用。 Q: 内存溢出和内存泄漏? 内存溢出: 简而言之&#xf…...

MySQL数据库数据类型

MySQL数据库数据类型分类 在MySQL数据库中,MySQL数据类型分有四大类:数值类型、文本/二进制类型、时间日期和String类型。以下是这四大类的具体类型: 数值类型 数值类型的范围和字节大小: tinyint类型 tinyint类型只有一个字节…...

【力扣】27. 移除元素 <快慢指针、首尾指针>

【力扣】27. 移除元素 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,必须仅使用 O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超…...

【每日一题】—— C. Challenging Cliffs(Codeforces Round 726 (Div. 2))

🌏博客主页:PH_modest的博客主页 🚩当前专栏:每日一题 💌其他专栏: 🔴 每日反刍 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮,缓称…...

想在金融界拥有一席之地吗—社科院杜兰大学金融管理硕士助你圆梦

追求高学历是为了什么?一纸证书吗?显然并非如此,只有读过研的人才有话语权。在上升一个平台后,你必然会发现,更高学历得到的不止是一张文凭。而是更大的平台、更广阔的视野、更包容的环境,更多样的文化。最…...

Moonbeam与Nodle网络集成,增添物联网功能

领先的波卡跨链互连开发平台Moonbeam近期宣布与Nodle Network达成XCM集成,将NODL Token带到Moonbeam生态之中。本次集成将会开启波卡中Moonbeam和Nodle网络以及通过Moonbeam互连合约相连的远程链之间的流动性。 Nodle网络是一个为物联网(Internet of Th…...

关于docker 在ubuntu16.04 上的安装

https://www.sohu.com/a/708313241_121368355 参考教程: https://www.runoob.com/docker/docker-image-usage.html 镜像网址 https://hub.docker.com/...

Cmder启动加速

Cmder是一个比较好用的命令行工具,可以通过修改默认Git地址提高启动速度: 打开vendor/init.bat添加本机Git地址,并且打开启动时间显示 :: Use /v command line arg or set to > 0 for verbose output to aid in debugging. set GIT_INSTA…...

【windows】windows上如何使用linux命令?

前言 windows上的bat命令感觉不方便,想在windows上使用linux命令。 有人提供了轮子,本文简单介绍一些该轮子的安装与使用,希望能够帮助到和我有一起需求的网友。 我的答案是busybox。 1.安装busybox.exe 在这个网站上安装busybox busyb…...

Docker Compose: 集合管理Docker的工具安装

Docker Compose:集合管理多个Docker容器的工具,在安装docker时windows,macos默认安装Docker Compose,linux需要自己手动安装 去官网https://github.com/docker/compose/releases下载需要的版本$ sudo chmod x ./docker-compose-linux-x86_64$ sudo cp .…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...

leetcode_69.x的平方根

题目如下 &#xff1a; 看到题 &#xff0c;我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历&#xff0c;我们是整数的平方根&#xff0c;所以我们分两…...

2025-05-08-deepseek本地化部署

title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek&#xff1a;小白也能轻松搞定&#xff01; 如何给本地部署的 DeepSeek 投喂数据&#xff0c;让他更懂你 [实验目的]&#xff1a;理解系统架构与原…...