5 - 声明式事务

传统事务流程:

Connection connection = JdbcUtils.getConnection();
try {//1. 先设置事务不要自动提交connection.setAutoCommit(false);//2. 进行各种 crud//多个表的修改,添加 ,删除select from 商品表 => 获取价格//修改用户余额update ...//修改库存量update//3. 提交connection.commit();
} catch (Exception e) {//4. 回滚conection.rollback();
}

使用 Spring 的声明式事务处理, 可以将上面三个子步骤分别写成一个方法,然后统一管理

1. 使用实例

1.1 创建 src\tx_ioc.xml 文件

<!-- 引入外部属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="${jdbc.userName}"></property><property name="password" value="${jdbc.password}"></property><property name="driverClass" value="${jdbc.driverClass}"></property><property name="jdbcUrl" value="${jdbc.url}"></property>
</bean>
<!-- 配置 JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><!-- 将上面的数据源分配给 jdbcTemplate --><property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="dataSourceTransactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启基于注解的声明式事务功能 -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
<!-- 加入自动扫描包 dao -->
<context:component-scan base-package="com.hspedu.spring.tx.dao"/>

1.2 修改对象

修改 GoodsService.java,加入声明式事务注解

@Transactional
public void buyGoodsByTx(int user_id, int goods_id, int num) {//查询到商品价格Float goods_price = goodsDao.queryPriceById(goods_id);//购买商品,减去余额goodsDao.updateBalance(user_id, goods_price * num);//模拟一个异常, 会发生数据库数据不一致现象// int i = 10 / 0;//更新库存goodsDao.updateAmount(goods_id, num);
}

1.3 声明式事务机制

  • 使用@Transactional 可以进行声明式事务控制;即将标识的方法中的,对数据库的操作作为一个事务管理
  • @Transactional 底层使用的仍然是AOP机制
  • 底层是使用动态代理对象来调用buyGoodsByTx

执行流程:

  1. 在执行buyGoodsByTx() 方法 先调用 事务管理器的 doBegin(),主要是将自动提交关掉  
  2. 然后调用 buyGoodsByTx()
  3. 如果执行没有发生异常,则调用 事务管理器的 doCommit()
  4. 如果发生异常 调用事务管理器的 doRollback()

2. 事务的传播机制

当有多个事务处理并存时,如何控制?

2.1 事务的传播机制种类

  • REQUIRED:如果现在有事务在运行,当前的方法就是在这个事务内运行
  • REQUIRED_NEW:当前方法必须新启动一个事务,在自己的事务内运行
  • SUPPORTS:如果现在有事务在运行,当前方法就在这个事务内运行,否则它可以不运行在事务中
  • NOT_SUPPORTE:当前方法不应该运行在事务内,如果有事务,该方法将挂起
  • MANDATORY:当前方法必须运行在事务内,如果没有运行在事务,则抛出异常
  • NEVER:当前方法不可以运行在事务内,如果运行在事务,则抛出异常
  • NESTED:如果现在有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新的事务,并运行在自己的事务里

重点分析 REQUIRED 和 REQUIRED_NEW

1)REQUIED(默认事务传播机制)

2)REQUIRES_NEW 

 3)事务的传播机制的设置方法

 4)例子

如果设置为 REQUIRES_NEW:

buyGoods2 如果错误,不会影响到 buyGoods(),即它们的事务是独立的

如果设置为 REQUIRED:

buyGoods2 和 buyGoods 是一个整体,只要有方法的事务错误,那么两个方法都不会执行成功.!


3.  事务的隔离级别

这个概念参考 MySQL

3.1 说明

默认的隔离级别, 就是 mysql 数据库默认的隔离级别 一般为 REPEATABLE_READ

查看数据库默认的隔离级别:

SELECT @@global.tx_isolation

3.2 事务隔离级别的设置及测试

1)默认

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void buyGoodsByTxISOLATION(int user_id, int goods_id, int num) {//查询到商品价格Float goods_price = goodsDao.queryPriceById(goods_id);System.out.println("第一次读取的价格 =" + goods_price);//测试一下隔离级别,在同一个事务中,查询一下价格goods_price = goodsDao.queryPriceById(goods_id);System.out.println("第二次读取的价格 =" + goods_price);
}

过程:在读完第一次数据后,通过 mysql 进行修改该数据

结果:两次读取到的价格是一样的,不会受到 MySQL 修改影响

2)READ_COMMITTED 隔离级别情况

语法:

 结果:两次读取到的价格是不一样的,数据是会受到 MySQL 修改影响


4. 事务的超时回滚

目的:如果一个事务执行的时间超过某个时间限制,就让该事务回滚

语法:

超出时间会抛出异常,事务回滚,原来的操作撤销 

注:

  • timeout = 2 表示 buyGoodsByTxTimeout 如果执行时间超过了2秒, 该事务就进行回滚
  • 如果没有设置 timeout, 默认是 -1,表示使用事务的默认超时时间,或者不支持

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

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

相关文章

“确定要在不复制其属性的情况下复制此文件?”解决方案(将U盘格式由FAT格式转换为NTFS格式)

文章目录 1.问题描述2.问题分析3.问题解决3.1 方法一3.2 方法二3.3 方法三 1.问题描述 从电脑上复制文件到U盘里会出现“确定要在不复制其属性的情况下复制此文件&#xff1f;”提示。 2.问题分析 如果这个文件在NTFS分区上&#xff0c;且存在特殊的安全属性。那么把它从NT…

请查收“链上天眼”2023年成绩单

1月10日是中国人民警察节&#xff0c;是一份责任&#xff0c;更一份安心&#xff0c;随着科技的发展&#xff0c;链上安全领域的技术与工具不断更新迭代&#xff0c;更加安全的Web3世界正在构建。 根据欧科云链安全团队统计&#xff0c;2023 年全球范围内利用虚拟货币进行诈骗…

Radzen Blazor Studio 脚手架框架解读

背景 组织管理管理准备使用Blazor这个工具实现&#xff0c;因为其有对应的 scaffold 脚手架&#xff0c;先构建数据库&#xff0c;然后通过向导&#xff0c;生成CRUD以及对应的接口&#xff0c;那么有必要看一下&#xff0c;其内部的代码结构是什么样的。 结构 接口层 有两类…

Python——for循环的嵌套

用Python坚持表白一百天&#xff0c;每天都送10朵花&#xff0c;一百天表白成功&#xff01; i1 for i in range(1,101):print(f"今天是表白的第{i}天&#xff0c;坚持ing")for j in range(1,11):print(f"送给你第{j}朵玫瑰花")print("小美我喜欢你&…

Hive 的 安装与使用

目录 1 安装 MySql2 安装 Hive3 Hive 元数据配置到 MySql4 启动 Hive5 Hive 常用交互命令6 Hive 常见属性配置 Hive 官网 1 安装 MySql 为什么需要安装 MySql? 原因在于Hive 默认使用的元数据库为 derby&#xff0c;开启 Hive 之后就会占用元数据库&#xff0c;且不与其他客户…

Mindspore 公开课 - prompt

prompt 介绍 Fine-Tuning to Prompt Learning Pre-train, Fine-tune BERT bidirectional transformer&#xff0c;词语和句子级别的特征抽取&#xff0c;注重文本理解Pre-train: Maked Language Model Next Sentence PredictionFine-tune: 根据任务选取对应的representatio…

算法通关村第十六关—滑动窗口经典问题(白银)

滑动窗口经典问题 一、最长子串专题 1.1 无重复字符的最长子串 LeetCode3给定一个字符串s&#xff0c;请你找出其中不含有重复字符的最长子串的长度。例如&#xff1a; 输入&#xff1a;s"abcabcbb" 输出&#xff1a;3 解释&#xff1a;因为无重复字符的最长子串是…

牛客周赛 Round 28 F

以后需要使用map&#xff0c;set进行二分&#xff0c;并且需要知道二分位置的信息时&#xff0c;不妨考虑使用树状数组进行维护 因为简单版本保证了每个数都为正整数&#xff0c;所以前缀和保证了一定的递增的&#xff0c;即有序的&#xff0c;那么考虑固定左端点&#xff0c;去…

多线程并发与并行

&#x1f4d1;前言 本文主要是【并发与并行】——并发与并行的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&…

python爬虫之线程与多进程知识点记录

一、线程 1、概念 线程 在一个进程的内部&#xff0c;要同时干多件事&#xff0c;就需要同时运行多个“子任务”&#xff0c;我们把进程内的这些“子任务”叫做线程 是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。一条线程指…

DAY01_Spring—Spring框架介绍IOCSpring工厂模式

目录 1 什么是框架2 Spring框架2.1 Spring介绍2.2 MVC模型说明2.3 IOC思想2.3.1 问题说明2.3.2 IOC说明 3 Spring IOC具体实现3.1 环境准备3.1.1 关于JDK说明3.1.2 检查JDK环境配置 3.2 创建项目3.3 关于Maven 命令3.3.1 install 命令3.3.2 clean 命令 3.4 添加jar包文件3.4.1 …

flutter使用getx进行数据状态管理,实现页面响应式

无论是什么样的应用&#xff0c;都还是需要最基础的数据来支撑的&#xff0c;而且不同的页面之间可能需要共享数据状态&#xff0c;这就显得数据状态管理非常有必要了。因为我这里使用了get依赖库&#xff0c;所以就可以直接在项目中使用getx来管理状态&#xff0c;不想再使用别…

服务器机房上架交付流程

服务器上架交付 服务器到货验收后&#xff0c;会进行机房机房上架&#xff0c;完成重装系统、网络配置后交付使用 1、到货验收 采购服务器到货后&#xff0c;会联合多部门进行SN、配置、数量等多方面验收&#xff0c;如数量是否匹配&#xff0c;配置是否相符等也会拆开机箱看看…

Python基础知识:整理10 异常相关知识

1 异常的捕获 1.1 基础写法 """基本语法&#xff1a;try:可能发生错误的代码except:如果出现异常&#xff0c;将执行的代码""" try:fr open("D:/abc.txt", "r", encoding"utf-8") except:print("出现异常…

APM传感器校准

文章目录 前言一、校准加速度计二、校准罗盘三、校准陀螺仪四、校平地平线 前言 固件&#xff1a;rover 4.2.3 地面站&#xff1a;独家汉化版QGC 一、校准加速度计 点击左上角软件图标-》载具设置-》传感器-》加速度计 飞控方向默认为None即可&#xff0c;点击确定 点击确…

德语怎么翻译,中文翻译成德文有何要求?

近年来&#xff0c;随着中德之间的贸易往来日益频繁&#xff0c;德语翻译需求在市场上持续升温。那么&#xff0c;如何做好德语翻译&#xff0c;特别是将中文翻译成德文需要注意哪些要求呢&#xff1f; 首先&#xff0c;深入理解中文原文的语境和含义至关重要。中文含蓄且抽象&…

存储的基本架构

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、存储的需求背景二、自下而上存储架构总结 一、存储的需求背景 1、人的身份信息需要存储 这种信息可以用关系型数据库&#xff0c;例如mysql&#xff0c;那种表…

第十二章 Java内存模型与线程(二)

文章目录 12.4 Java与线程12.4.1 线程的实现12.4.2 Java线程调度12.4.3 状态转换 12.4 Java与线程 12.4.1 线程的实现 实现线程主要有三种方式&#xff1a;使用内核线程实现&#xff08;1&#xff1a; 1 实现&#xff09;&#xff0c;使用用户线程实现&#xff08;1&#xff…

FFmpeg 入门

1. 编译 参考文档&#xff1a;FFmpeg编译和集成(FFmpeg开发基础知识)&#xff0c;重点注意这句话&#xff1a; 在MSYS2 Packages可以查到云仓库有哪些包&#xff0c;直接安装可节约大量时间。 注意&#xff1a;这个路径可自定义 吐槽 在看到这篇文章之前&#xff0c;花了大…

腾讯云服务器购买指南,2024更新购买步骤

腾讯云服务器购买流程很简单&#xff0c;有两种购买方式&#xff0c;直接在官方活动上购买比较划算&#xff0c;在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵&#xff0c;但是自定义购买云服务器CPU内存带宽配置选择范围广&#xff0c;活动上购买只能选择固定的活动…