本地事务简介

本地事务简介

1 事务基本性质

数据库事务的几个特性:原子性(Automicity)、一致性(Consistency)、隔离性或独立性(islation)和持久性(Durability),简称ACID。

  • 原子性:一系列的操作,其整体不可拆分,要么同时成功,要么同时失败。

  • 一致性:数据在事务的前后,业务整体一致。

    • 转账 。A:1000; B:1000 ;转200
      事务成功。 A:800, B:1200
  • 隔离性:事务之间互相隔离。

  • 持久性:一旦事务成功,数据一定会记录在数据库。

2 事务的隔离级别
隔离级别特点
Read Uncommitted允许读取未提交的数据
Read committed只能读取已提交的数据
Repeatable Read同一事务中多次读取同一数据结果一致
Serializable事务完全串行化,按顺序执行
2.1 Read Uncommitted
场景描述

假设有一个银行账户表 accounts,记录用户的账户余额。现在有两个并发事务:

  1. 事务 A:从账户中扣除 100 元。
  2. 事务 B:查询账户余额。
数据库初始状态

假设账户初始余额为 1000 元。

事务操作步骤
  1. 事务 A 开始
    • 查询账户余额:SELECT balance FROM accounts WHERE account_id = 1;(结果为 1000 元)
    • 扣除 100 元:UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;(此时账户余额变为 900 元,但事务 A 还未提交)
  2. 事务 B 开始
    • 查询账户余额:SELECT balance FROM accounts WHERE account_id = 1;(结果为 900 元,因为事务 A 的未提交数据被读取到了)
  3. 事务 A 回滚
    • 由于某些原因,事务 A 回滚,撤销了之前的更新操作。此时账户余额恢复为 1000 元。
  4. 事务 B 结束
    • 事务 B 查询到的余额是 900 元,但实际上账户的真实余额是 1000 元。
问题分析
  • 脏读:事务 B 读取到了事务 A 未提交的数据(900 元),而事务 A 最终回滚,导致事务 B 查询到的数据是不正确的。这种现象称为脏读
Read Uncommitted 的特点
  • Read Uncommitted 隔离级别下,事务可以读取到其他事务尚未提交的数据。
  • 这种隔离级别允许并发性能最高,但数据一致性最差,容易出现脏读问题。
2.2 Read Committed
场景描述

假设有一个库存表 inventory,记录商品的数量。现在有两个并发事务:

  1. 事务 A:更新商品的数量。
  2. 事务 B:查询商品的数量。
数据库初始状态

假设商品的初始数量为 100。

事务操作步骤
  1. 事务 A 开始
    • 查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(结果为 100)
    • 更新商品数量:UPDATE inventory SET quantity = quantity - 10 WHERE product_id = 1;(此时商品数量变为 90,但事务 A 还未提交)
  2. 事务 B 开始
    • 查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(结果为 100,因为事务 A 的更新尚未提交)
  3. 事务 A 提交
    • 提交事务 A,更新操作生效,商品数量变为 90。
  4. 事务 B 再次查询
    • 再次查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(结果为 90,因为事务 A 已提交)
问题分析
  • 避免脏读:事务 B 在事务 A 提交之前查询到的商品数量是 100,而不是事务 A 未提交的 90。这避免了脏读问题。
  • 不可重复读:事务 B 在事务 A 提交后再次查询,结果从 100 变为 90。这种现象称为不可重复读,因为同一个事务在不同时间读取到的数据不一致。
  • 幻读:如果事务 B 在事务 A 提交之前查询商品数量,然后事务 A 插入了一条新的商品记录,事务 B 再次查询时可能会发现多了一条记录。这种现象称为幻读
Read Committed 的特点
  • 避免脏读:事务只能读取到其他事务已经提交的数据。
  • 可能出现不可重复读和幻读:由于事务 B 在事务 A 提交前后读取到的数据不一致,可能会出现不可重复读和幻读问题。
  • 并发性能较好:相比更高隔离级别(如 Repeatable ReadSerializable),Read Committed 的并发性能更好,因为它允许更多的并发操作。
2.3 Repeatable Read
场景描述

假设有一个商品库存表 inventory,记录商品的数量。现在有两个并发事务:

  1. 事务 A:查询并更新商品的数量。
  2. 事务 B:查询商品的数量。
数据库初始状态

假设商品的初始数量为 100。

事务操作步骤
  1. 事务 A 开始
    • 查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(结果为 100)
    • 更新商品数量:UPDATE inventory SET quantity = quantity - 10 WHERE product_id = 1;(此时商品数量变为 90,但事务 A 还未提交)
  2. 事务 B 开始
    • 查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(结果为 100,因为事务 A 的更新尚未提交)
  3. 事务 A 提交
    • 提交事务 A,更新操作生效,商品数量变为 90。
  4. 事务 B 再次查询
    • 再次查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(结果仍为 100,因为事务 B 在同一个事务中,读取到的结果是一致的)
问题分析
  • 避免脏读:事务 B 在事务 A 提交之前查询到的商品数量是 100,而不是事务 A 未提交的 90。这避免了脏读问题。
  • 避免不可重复读:事务 B 在同一个事务中多次查询商品数量,结果始终为 100,即使事务 A 已提交,事务 B 仍然读取到的是事务开始时的一致数据。这避免了不可重复读问题。
  • 可能出现幻读:虽然 Repeatable Read 避免了不可重复读,但在某些数据库实现中,如果事务 A 插入或删除了记录,事务 B 可能会看到不同的结果集。这种现象称为幻读
Repeatable Read 的特点
  • 避免脏读和不可重复读:事务在同一个事务中多次读取同一数据的结果是一致的。
  • 可能出现幻读:在某些数据库实现中,如果事务 A 插入或删除了记录,事务 B 可能会看到不同的结果集。
  • 并发性能较好:相比 SerializableRepeatable Read 的并发性能更好,因为它允许更多的并发操作。
2.4 Serializable
场景描述

假设有一个商品库存表 inventory,记录商品的数量。现在有两个并发事务:

  1. 事务 A:查询并更新商品的数量。
  2. 事务 B:查询商品的数量。
数据库初始状态

假设商品的初始数量为 100。

事务操作步骤
  1. 事务 A 开始
    • 查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(结果为 100)
    • 更新商品数量:UPDATE inventory SET quantity = quantity - 10 WHERE product_id = 1;(此时商品数量变为 90,但事务 A 还未提交)
  2. 事务 B 开始
    • 查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(事务 B 会被阻塞,直到事务 A 提交或回滚)
  3. 事务 A 提交
    • 提交事务 A,更新操作生效,商品数量变为 90。
  4. 事务 B 继续执行
    • 查询商品数量:SELECT quantity FROM inventory WHERE product_id = 1;(结果为 90,因为事务 A 已提交)
问题分析
  • 避免脏读:事务 B 在事务 A 提交之前无法读取数据,因此不会读取到事务 A 未提交的数据。
  • 避免不可重复读:事务 B 在同一个事务中多次查询商品数量,结果始终为 90,即使事务 A 已提交,事务 B 仍然读取到的是事务开始时的一致数据。
  • 避免幻读:事务 B 在事务 A 提交之前无法读取数据,因此不会看到事务 A 插入或删除的记录。
Serializable 的特点
  • 完全避免并发问题Serializable 确保所有事务按顺序执行,完全避免了脏读、不可重复读和幻读。
  • 并发性能最低:由于事务必须按顺序执行,不能并行,因此并发性能最低。
  • 适用场景:适用于对数据一致性要求极高的场景,如金融交易系统、账务系统等。
3 事务的传播行为

在 Spring 中,事务传播行为(Transaction Propagation Behavior)定义了在一个事务中调用另一个事务方法时,事务如何被传播和管理。Spring 提供了多种事务传播行为,每种行为都对应不同的事务管理策略。以下是常见的事务传播行为及其解释:

传播行为当前有事务时当前无事务时
PROPAGATION_REQUIRED加入当前事务创建新事务
PROPAGATION_SUPPORTS加入当前事务非事务执行
PROPAGATION_MANDATORY加入当前事务抛出异常
PROPAGATION_REQUIRES_NEW创建新事务,挂起当前事务创建新事务
PROPAGATION_NOT_SUPPORTED挂起当前事务,非事务执行非事务执行
PROPAGATION_NEVER抛出异常非事务执行
PROPAGATION_NESTED创建嵌套事务创建新事务

实例代码:

#在注解上指定事务的传播行为
@Transational(Propagation=Propagation.REQUIRES_NEWS)
#方法签名
public void transaction(){...}
4 代理对象

在同一个类中,编写两个方法,内部调用的时候,会导致事务设置失效。原因是没有用到代理对象。

// TODO ps:貌似新版spring已经优化了,可以内部调用了。

解决方法:通过代理对象调用方法

①引入依赖

<dependency><groupId>org.springframe.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

②在启动类上加上注解@EnableAspectJAutoProxy(exposeProxy=true)

@EnableAspectJAutoProxy(exposeProxy=true)
@SpringBootApplication
public class Application {...}

③在类中使用代理对象如下:

OrderServiceImpl orderService = (OrderServiceImpl) AopContext.currentProxy();
// 在OrderServiceImpl类内部,通过代理对象调用自身的method1方法和method2方法
orderService.method1();
orderService.method2();

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

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

相关文章

PyQt组态软件 拖拽设计界面测试

PyQt组态软件测试 最近在研究PyQt,尝试写个拖拽设计界面的组态软件&#xff0c;目前实现的功能如下&#xff1a; 支持拖入控件&#xff0c;鼠标拖动控件位置 拖动控件边缘修改控件大小支持属性编辑器&#xff0c;修改当前选中控件的属性 拖动框选控件&#xff0c;点选控件 控…

软件评测师复习之计算机网络(4)

目录 (一)1.网络功能和分类2.OSI七层模型3.TCP/IP协议4.传输介质(二)1.通信方式和交换方式2.IP地址3.IPv64.网络规划与设计5.磁盘冗余阵列6.网络存储技术(一) 1.网络功能和分类 计算机网络功能:数据通信、资源共享、负载均衡、高可靠性 按分布范围和拓扑结构划分: 网络分类…

机器学习-1:线性回归

常用的线性回归模型主要有以下这些 简单线性回归多元线性回归多项式回归岭回归套索回归弹性网络回归逐步回归 一.简单的一元线性回归 1.导入必备的库 #导入必备的库 import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.model_selection …

SQL SERVER的PARTITION BY应用场景

SQL SERVER的PARTITION BY关键字说明介绍 PARTITION BY关键字介绍具体使用场景排名计算累计求和分组求最值分组内百分比计算分组内移动平均计算分组内数据分布统计分组内数据偏移计算 总结 PARTITION BY关键字介绍 在SQL SERVER中&#xff0c;关键字PARTITION BY主要用于窗口函…

NO.18十六届蓝桥杯备战|循环嵌套|乘法表|斐波那契|质数|水仙花数|(C++)

循环嵌套 循环嵌套的使⽤ while &#xff0c; do while &#xff0c; for &#xff0c;这三种循环往往会嵌套在⼀起才能更好的解决问题&#xff0c;就是我们所说的&#xff1a;循环嵌套。这三种循环都可以任意嵌套使⽤ ⽐如&#xff1a; 写⼀个代码&#xff0c;打印⼀个乘法⼝…

leetcode - hot100 - python - 专题一:哈希

1、两数之和 简单 题目&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。你可…

JavaEE-SpringBoot快速入门

文章目录 本节目标Maven什么是Maven创建一个Maven项目maven项目功能maven的依赖管理全球仓库, 私服, 本地服务器, 配置国内镜像 第一个SpringBoot项目创建项目运行SpringBoot程序 SpringBoot原理初步Web服务器 总结 本节目标 了解什么是maven, 配置国内源使用Springboot创建项…

【Viper】配置格式与支持的数据源与go案例

Viper 是一个用于 Go 应用程序的配置管理库&#xff0c;支持多种配置格式和数据源。 安装依赖 go get github.com/spf13/viper go get github.com/spf13/viper/remote go get go.etcd.io/etcd/client/v3"github.com/spf13/viper/remote"要写在etcd客户端import里 1…

【C/C++】后缀表达式 蓝桥杯/ACM备赛

核心考点&#xff1a;1.栈的应用 2.字符串处理 题目描述 所谓后缀表达式是指这样的一个表达式&#xff1a;式中不再引用括号&#xff0c;运算符号放在两个运算对象之后&#xff0c;所有计算按运算符号出现的顺序&#xff0c;严格地由左而右新进行&#xff08;不用考虑运算符的…

【AI实践】deepseek支持升级git

当前Windows 11 WSL的git是2.17&#xff0c;Android Studio提示需要升级到2.19版本 网上找到指导文章 安装git 2.19.2 cd /usr/src wget https://www.kernel.org/pub/software/scm/git/git-2.19.2.tar.gz tar xzf git-2.19.2.tar.gz cd git-2.19.2 make prefix/usr/l…

QEMU 搭建 Ubuntu x86 虚拟机

1. 安装 QEMU 在 Ubuntu 系统中&#xff0c;可以通过以下命令安装 QEMU&#xff1a; sudo apt-get update sudo apt-get install qemu-system-x86_64 qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager2. 创建虚拟硬盘镜像 qemu-img create -f raw ubuntu…

Linux驱动层学习:Linux 设备树

设备树是一种数据结构&#xff0c;包含多个节点&#xff0c;用于描述硬件设备及其配置信息&#xff0c;它通常用于嵌入式系统中&#xff0c;尤其是在Linux操作系统中&#xff0c;帮助操作系统识别和管理硬件资源&#xff0c;设备树不是代码&#xff0c;而是一种用数据描述硬件信…

金蝶云星空与钉钉高效数据集成案例分享

金蝶云星空数据集成到钉钉的技术案例分享 在企业信息化系统中&#xff0c;数据的高效流动和实时反馈是提升业务效率的关键。本文将聚焦于一个具体的系统对接集成案例&#xff1a;如何将金蝶云星空的数据集成到钉钉&#xff0c;并实现审核状态的回传提示。 本次集成方案名为“…

图形渲染(一)——Skia、OpenGL、Mesa 和 Vulkan简介

1.Skia —— 2D 图形库 Skia 是一个 2D 图形库&#xff0c;它的作用是为开发者提供一个高层次的绘图接口&#xff0c;方便他们进行 2D 图形渲染&#xff08;比如绘制文本、形状、图像等&#xff09;。Skia 本身不直接管理 GPU 或进行底层的渲染工作&#xff0c;而是通过 底层图…

GIT提错分支,回滚提交

1. 准备示例 假设我们有三次提交&#xff1a; test1&#xff1a;需要在 master 分支提交test2、test3&#xff1a;需要在 develop 分支提交 远端线上记录 2. 步骤 选择需要回退的记录&#xff1a; 选中需要回退的 commit&#xff0c;选择 Reset Current Branch to Here...。…

【原创】在ubuntu中搭建gradle开发环境

检查Linux版本 rootwww:~# hostnamectlStatic hostname: www.0x88.comIcon name: computer-vmChassis: vmMachine ID: 30fa955a36be492ca459599ef20bc508Boot ID: 37084dbe36f44adaa075e8f9a98f132eVirtualization: kvm Operating System: Ubuntu 22.04.5 LTSKernel: Linux 5.…

【JavaEE进阶】MyBatis入门

目录 &#x1f334;前言 &#x1f332;什么是MyBatis? &#x1f333;准备工作 &#x1f6a9;创建工程 &#x1f6a9;配置数据库连接字符串 &#x1f6a9;数据准备 &#x1f6a9;编写持久层代码 &#x1f343;单元测试 &#x1f334;前言 在应⽤分层学习时,我们了解到…

以太网详解(八)传输层协议:TCP/UDP 协议

文章目录 传输层协议概述为什么需要传输层&#xff1f;传输层功能网络层与传输层在实现 “端到端” 传输的异同两类服务:面向连接/无连接服务 传输控制协议 TCPTCP 协议数据单元格式TCP 的重传机制快重传和快恢复快重传举例快恢复算法 用户数据报协议 UDPUDP 概述UDP 基本工作过…

Electron 客户端心跳定时任务调度库调研文档 - Node.js 任务调度库技术调研文档

Electron 客户端心跳定时任务调度库调研文档 - Node.js 任务调度库技术调研文档 本文将对七个流行的定时任务调度库&#xff1a;node-cron、rxjs、bull、node-schedule、agenda、bree、cron。这些库都可以用来处理定时任务&#xff0c;但它们的特点和适用场景有所不同。我们将从…

DeepSeek 开放平台无法充值 改用其他平台API调用DeepSeek-chat模型方法

近几天DeepSeek开放平台无法充值目前已经关闭状态&#xff0c;大家都是忙着接入DeepSeek模型 &#xff0c;很多人想使用DeepSeek怎么办&#xff1f; 当然还有改用其他平台API调用方法&#xff0c;本文以本站的提供chatgpt系统为例&#xff0c;如何修改DeepSeek-chat模型API接口…