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 年全球范围内利用虚拟货币进行诈骗…

采购申请检查并警告提示

设置&#xff1a;采购申请检查并警告提示 增强&#xff1a;MEREQ001 EXIT_SAPLMEREQ_005 &--------------------------------------------------------------------- *& 包含 ZXM02U05 &--------------------------------------------------------------------- …

Radzen Blazor Studio 脚手架框架解读

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

L1-024 后天(Java)

如果今天是星期三&#xff0c;后天就是星期五&#xff1b;如果今天是星期六&#xff0c;后天就是星期一。我们用数字1到7对应星期一到星期日。给定某一天&#xff0c;请你输出那天的“后天”是星期几。 输入格式&#xff1a; 输入第一行给出一个正整数D&#xff08;1 ≤ D ≤…

布隆过滤器原理(易理解版)

当我们说布隆过滤器时&#xff0c;可以将其想象成一个特殊的盒子&#xff0c;这个盒子可以判断某个东西是否在里面。但是&#xff0c;这个盒子并不存储实际的东西&#xff0c;而是用一些特殊的方法来判断。 盒子&#xff08;位数组&#xff09;&#xff1a; 有一个盒子&#xf…

Oracle sql sum函数返回null,默认值0

在Oracle SQL中&#xff0c;当你使用SUM函数对一组值进行求和时&#xff0c;如果这组值中包含NULL&#xff0c;那么SUM函数将忽略这些NULL值&#xff0c;并返回非NULL值的总和。 如果你希望在SUM函数返回NULL时有一个默认值&#xff0c;你可以使用COALESCE或NVL函数。 使用CO…

深度学习烦人的基础知识(1)---@在bash中的作用---positional parameter详解

文章目录 序Positional parameter练习题 Special parameter练习题 序 深度学习&#xff0c;反展到现在&#xff0c;真的是要融会贯通很多东西。遇到便补吧&#xff01; 想直接知晓答案的&#xff0c;请到最后一个练习题&#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;因为无重复字符的最长子串是…

【Java万花筒】数据之舞:Java数据库连接与操作库全景视角

数据库连接与操作&#xff1a;Java 应用开发者的综合指南 前言 随着Java应用的不断发展&#xff0c;数据库连接与操作成为关键技能之一。本文将深入探讨主流Java库&#xff0c;涵盖了JDBC、Hibernate、MyBatis、Spring Data JPA、Apache Commons DBUtils、JOOQ以及Querydsl。…

牛客周赛 Round 28 F

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

多线程并发与并行

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

自动化测试理论(1)—概述需要掌握的内容

要在自动化测试领域取得成功&#xff0c;需要掌握一系列技能和概念。以下是一些关键的内容&#xff1a; 编程语言&#xff1a; 了解并精通至少一种编程语言&#xff0c;如Python&#xff0c;Java&#xff0c;JavaScript等。编写自动化测试脚本通常需要编程技能。 自动化测试框…

SpringBoot3

有用的新特性 JDK8-19 新增了不少新特性&#xff0c;这里我们把实际常用的新特性&#xff0c;给大家介绍一下。包括以下几个方面&#xff1a; Java RecordSwich 开关表达式Text Block 文本块var 声明局部变量sealed 密封类 Java14 中预览的新特性叫做 Record &#xff0c;在…

explorer.exe 作用

Explorer.exe是什么 在Windows操作系统中&#xff0c;Explorer.exe是桌面进程的意思&#xff0c;它负责显示用户桌面信息&#xff0c;如果用户将它结束掉就看不到桌面上的任何图标了&#xff0c;相当于Windows操作系统中的人机交互界面&#xff0c;其重要性不言而喻。如果用户发…

【算法笔记】分支限界专题

分支限界 整体结构 本质上感觉还是遍历解树剪枝&#xff0c;但是配合优先队列使用以后可以更好的找到最优解。 例题 P8011 ⾛迷宫 对于迷宫问题&#xff0c;某一节点的关联节点指的是它四个方向上相邻的节点。 要利用flag数组确保不会重复访问。 void bfs(){//1、初始化队…

重写equals方法为什么还要重写hashcode方法?

目录 什么是 hashcode&#xff08;哈希码、散列码&#xff09;&#xff1f; 为什么 equals() 方法要重写&#xff1f; hashCode() 与 equals() 的关系 重写equals方法为什么还要重写hashcode方法&#xff1f; 什么是 hashcode&#xff08;哈希码、散列码&#xff09;&#…