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);
}

事务传播行为的可选值

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

求分享如何批量压缩视频的容量的方法

视频内存过大,不但特别占内存,而且还会使手机电脑出现卡顿的现象,除此之外,如果我们想发送这些视频文件可能还会因为内存太大无法发送。因此,我们可以批量地压缩视频文件的内存大小,今天小编要来分享一招&a…

二进制链表转整数

给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。 请你返回该链表所表示数字的 十进制值 。 示例 1: 输入:head [1,0,1] 输出:5 解释:二进制数 (101) 转化为十进…

获取淘宝商品详情数据的几种方法(商品标题、商品价格、商品销量、详情图片、商品主图

淘宝作为中国最大的电商平台之一,拥有海量的商品信息和用户数据。对于电商从业人员和数据分析师来说,了解淘宝商品详情数据是非常重要的。本文将介绍几种获取淘宝商品详情数据的高效方法,并详细探讨每种方法的优缺点。 一、淘宝 API 淘宝开放…

Flink - souce算子

水善利万物而不争,处众人之所恶,故几于道💦 目录 1. 从Java的集合中读取数据 2. 从本地文件中读取数据 3. 从HDFS中读取数据 4. 从Socket中读取数据 5. 从Kafka中读取数据 6. 自定义Source 官方文档 - Flink1.13 1. 从Java的集合中读取数据 …

【话题】感觉和身边其他人有差距怎么办?也许自我调整很重要

每个人能力有限,水平高低不同,我们身在大环境里,虽然在同一个起跑线上,但是时间久了,你会发现,并越来越感觉到和身边其他人有了差距,慢慢的会有一定的落差感,怎么办呢!通…

接口相似数据结构复用率高?Apipost这招搞定!

在API设计和开发过程中,存在许多瓶颈,其中一个主要问题是在遇到相似数据结构的API时会产生重复性较多的工作:在每个API中都编写相同的数据,这不仅浪费时间和精力,还容易出错并降低API的可维护性。 为了解决这个问题&a…

SAS-数据集SQL水平合并

一、SQL水平合并基本语法 sql的合并有两步,step1:进行笛卡尔乘积运算,第一个表的每一行合并第二个表的每一行,即表a有3行,表b有3行,则合并后3*39行。笛卡尔过程包含源数据的所有列,相同列名会合…

【LeetCode每日一题】——566.重塑矩阵

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 566.重塑矩阵 四【题目描述】 在 MATLAB 中&…

【QT学习】01:helloqt

helloqt OVERVIEW helloqt一、helloqt1.使用向导创建2.手动创建3.pro文件4.Qt应用程序框架 二、按钮创建main.cppmywidget.cpp 三、对象模型1.对象树引入2.存在的问题 一、helloqt 创建一个qt项目,可以使用creator的向导创建,也可自己手动创建&#xff…

时间复杂度为O(n2)的三种简单排序算法

1.冒泡排序 冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素进行比较,看是否满足大小关系要求。如果不满足就让它俩互换。一次冒泡会让至少少一个元素移动到它应该在的位置,重复n次,就完成了n个数据的排序工作。 /*** …

JavaEE初阶之网络初识

一、网络发展史 1.1独立模式 独立模式:计算机之间相互独立; 1.2网络互连 随着时代的发展,越来越需要计算机之间互相通信,共享软件和数据,即以多个计算机协同工作来完成业务,就有了网络互连。网络互连:将多台计算机连接在一起,完成数据共享。 数据共享本质是网络数据…

Pytorch深度学习-----神经网络之池化层用法详解及其最大池化的使用

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Co…

39.手机导航

手机导航 html部分 <div class"phone"><div class"content"><img class"active" src"./static/20180529205331_yhGyf.jpeg" alt"" srcset""><img src"./static/20190214214253_hsjqw…

14-1_Qt 5.9 C++开发指南_网络编程及主机信息查询_HostInfo

Qt 网络模块提供了用于编写 TCP/IP 客户端和服务器端程序的各种类&#xff0c;如用于 TCP 通信的QTcpSocket 和 QTcpServer&#xff0c;用于 UDP 通信的 QUdpSocket&#xff0c;还有用于实现 HTTP、FTP 等普通网络协议的高级类如 QNetworkRequest&#xff0c;QNetworkReply 和Q…

SpringBoot 入门

0目录 1.SpringBoot简介&#xff1b;优点和目录结构 2.实战 3.YML基本语法 4.集成Mybatis 1.SpringBoot简介&#xff1b;优点和目录结构 2.实战 创建工程 去s 降低错误率&#xff0c;更改地址 选择Maven 组和名称 修改版本&#xff0c;加入依赖 新建controller …

f12 CSS网页调试_css样式被划了黑线怎么办

我的问题是这样的 class加上去了,但是样式不生效,此时可能是样式被其他样式覆盖了, 解决方案就是 给颜色后边添加一个!important

Python 进阶(三):正则表达式(re 模块)

❤️ 博客主页:水滴技术 🌸 订阅专栏:Python 入门核心技术 🚀 支持水滴:点赞👍 + 收藏⭐ + 留言💬 文章目录 1. 导入re模块2. re模块中的常用函数2.1 re.search()2.2 re.findall()2.3 re.sub()2.4 re.compile()2.5 re.split()3. 正则表达式的语法4. 匹配对象的属性和

淘宝资源采集(从零开始学习淘宝数据爬取)

1. 为什么要进行淘宝数据爬取&#xff1f; 淘宝数据爬取是指通过自动化程序从淘宝网站上获取数据的过程。这些数据可以包括商品信息、销售数据、评论等等。淘宝数据爬取可以帮助您了解市场趋势、优化您的产品选择以及提高销售额。 淘宝作为全球的电商平台&#xff0c;每天都有…

jmeter中json提取器,获取多个值,并通过beanshell组成数组

jmeter中json提取器介绍 特别说明&#xff1a;**Compute concatenation var(suffix_ALL)&#x1f617;*如果找到许多结果&#xff0c;则插件将使用’ &#xff0c; 分隔符将它们连接起来&#xff0c;并将其存储在名为 _ALL的var中 json提取器调试 在查看结果树中选择JSON Pat…

FSM:Full Surround Monodepth from Multiple Cameras

参考代码&#xff1a;None 介绍 深度估计任务作为基础环境感知任务&#xff0c;在基础上构建的3D感知才能更加准确&#xff0c;并且泛化能力更强。单目的自监督深度估计已经有MonoDepth、ManyDepth这些经典深度估计模型了&#xff0c;而这篇文章是对多目自监督深度估计进行探…