Mysql_数据库事务

news2024/11/17 23:36:38

文章目录

😊 @ 作者:Lion J
💖 @ 主页: https://blog.csdn.net/weixin_69252724
🎉 @ 主题: MySQL__事务)
⏱️ @ 创作时间:2024年04月26日
————————————————

这里写目录标题

  • 文章目录
    • 什么是事务呢?
    • 那数据库事务有什么作用呢??
    • 并发事务会带来哪些问题呢?
      • ●脏读:
      • ●丢失修改:
      • ●不可重复读:
      • ●幻读:
    • 并发事务的控制有什么?
      • **MVCC
    • 一致性非锁定读 和 锁定读
      • 一致性非锁定读
      • 锁定读
    • MVCC的实现?
      • 隐藏字段
      • undo-log
      • 在 可重复读 与 串行化 的级别下MVCC的差异?

什么是事务呢?

事务就是由单独单元的一个或多个sql语句组成,在这个单元中,每个sql语句都是相互依赖的。而整个单独单元是作为一个不可分割的整体存在,类似于化学当中的原子(一种不可分割的最小单位)。

往通俗的讲就是,事务就是一个整体,里面的内容要么都执行成功,要么都不成功。不可能存在部分执行成功而部分执行不成功的情况。
就是说如果单元中某条sql语句一旦执行失败或者产生错误,那么整个单元将会回滚(返回最初状态)。所有受到影响的数据将返回到事务开始之前的状态,但是如果单元中的所有sql语句都执行成功的话,那么该事务也就被顺利执行。

我们的数据都是通过各种不同技术的存储引擎来引导存储的,不同的存储引擎,都有各自的特点。在mysql中,常见的存储引擎有innodb、myisam等。其中innodb支持事务(transaction),而myisam.等不支持事务。

可以通过show engines;语句来查看mysql支持的存储引擎

   show engines;

比如在生活中举个例子:
事务最经典也经常被拿出来说例子就是转账了。
假如小明要给小红转账 1000 元,这个转账会涉及到两个关键操作,这两个操作必须都成功或者都失败。

  1. 将小明的余额减少 1000 元
  2. 将小红的余额增加 1000 元。
    事务会把这两个操作就可以看成逻辑上的一个整体,这个整体包含的操作要么都成功,要么都要失败。这样就不会出现小明余额减少而小红的余额却并没有增加的情况。

那数据库事务有什么作用呢??

简单来说,数据库事务可以保证多个对数据库的操作(也就是 SQL 语句)构成一个逻辑上的整体。构成这个逻辑上的整体的这些数据库操作遵循:要么全部执行成功,要么全部不执行 。

开启一个事务(对于mysql8来说)

BEGIN 开始一个事务

update... insert... delete ...


ROLLBACK 事务回滚
COMMIT 事务确认

在这里插入图片描述

对于关系型数据库来说(mysql, sql server, oracle)事务来说都有,ACID特性
●原子性(Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
●一致性(Consistency):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
●隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
●持久性(Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

在这里插入图片描述

注意!!:
只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是需要满足的条件,C 是最终的目的!
在这里插入图片描述


并发事务会带来哪些问题呢?

在单体应用程序中(因为我对微服务项目不够深入__🤣),多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一数据进行操作)。并发虽然是必须的,但可能会导致以下的问题

●脏读:

一个事务读取数据并且对数据进行了修改,这个修改对其他事务来说是可见的,即使当前事务没有提交。这时另外一个事务读取了这个还未提交的数据,但第一个事务突然回滚,导致数据并没有被提交到数据库,那第二个事务读取到的就是脏数据,这也就是脏读的由来。

顾名思义就是读取到了需要丢弃的数据

例如:事务 1 读取某表中的数据 A=20,事务 1 修改 A=A-1,事务 2 读取到 A = 19,事务 1 回滚导致对 A 的修改并未提交到数据库, A 的值还是 20但是此时,事务2读取到的A仍然是A=19

●丢失修改:

在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。

例如:事务 1 读取某表中的数据 A=20,事务 2 也读取 A=20,事务 1 先修改 A=A-1,事务 2 后来也修改 A=A-1,最终结果 A=19,事务 1 的修改被丢失。

●不可重复读:

指在一个事务内多次读同一数据。
在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,**由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。**这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。

●幻读:

幻读与不可重复读类似。

不可重复读的重点是内容修改或者记录减少比如多次读取一条记录发现其中某些记录的值被修改;
幻读的重点在于记录新增比如多次执行同一条查询语句
时,发现查到的记录增加了。

它发生在一个事务读取了几行数据,接着另一个并发事务插入了一些数据时。在随后的查询中,第一个事务就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

例如:事务 2 读取某个范围的数据,事务 1 在这个范围插入了新的数据,事务 2 再次读取这个范围的数据发现相比于第一次读取的结果多了新的数据。

并发事务的控制有什么?

MySQL 中并发事务的控制方式无非就两种:
锁 和 MVCC。

  1. 锁可以看作是悲观控制的模式
  2. 多版本并发控制(MVCC,Multiversion concurrency control)可以看作是乐观控制的模式。

锁控制方式下会通过锁来显示控制共享资源而不是通过调度手段,MySQL 中主要是通过 读写锁 来实现并发控制。

●共享锁:又称读锁,事务在读取记录的时候获取共享锁,允许多个事务同时获取(锁兼容)。
●排他锁:又称写锁/独占锁,事务在修改记录的时候获取排他锁,不允许多个事务同时获取。如果一个记录已经被加了排他锁,那其他事务不能再对这条记录加任何类型的锁(锁不兼容)

读写锁可以做到读读并行,但是无法做到写读、写写并行。另外,根据根据锁粒度的不同,又被分为 表级锁和 行级锁 。

InnoDB引擎 不光支持表级锁,还支持行级锁,默认为行级锁。行级锁的粒度更小,仅对相关的记录上锁即可(对一行或者多行记录加锁),所以对于并发写入操作来说, InnoDB 的性能更高。
不论是表级锁还是行级锁,都存在共享锁(Share Lock)和排他锁(Exclusive Lock)这两类。

**MVCC

MVCC 是一种多版本并发控制机制,用于在多个并发事务同时读写数据库时保持数据的一致性和隔离性。它是通过在每个数据行上维护多个版本的数据来实现的。当一个事务要对数据库中的数据进行修改时,MVCC 会为该事务创建一个数据快照,而不是直接修改实际的数据行

MVCC 在 MySQL 中实现所依赖的手段主要是: 隐藏字段、read view、undo log。

  1. undo log : undo log 用于记录某行数据的多个版本的数据。
  2. read view 和 隐藏字段 : 用来判断当前版本数据的可见性。

1、读操作(SELECT):
当一个事务执行读操作时,它会使用快照读取。快照读取是基于事务开始时数据库中的状态创建的,因此事务不会读取其他事务尚未提交的修改
具体工作情况如下:
●对于读取操作,事务会查找符合条件的数据行,并选择符合其事务开始时间的数据版本进行读取
●如果某个数据行有多个版本,事务会选择不晚于其开始时间的最新版本,确保事务只读取在它开始之前已经存在的数据。
●事务读取的是快照数据,因此其他并发事务对数据行的修改不会影响当前事务的读取操作。

2、写操作(INSERT、UPDATE、DELETE):
当一个事务执行写操作时,它会生成一个新的数据版本,并将修改后的数据写入数据库。
具体工作情况如下:
●对于写操作,事务会为要修改的数据行创建一个新的版本,并将修改后的数据写入新版本。
●新版本的数据会带有当前事务的版本号,以便其他事务能够正确读取相应版本的数据。
●原始版本的数据仍然存在,供其他事务使用快照读取,这保证了其他事务不受当前事务的写操作影响。

3、事务提交和回滚:
●当一个事务提交时,它所做的修改将成为数据库的最新版本,并且对其他事务可见。
●当一个事务回滚时,它所做的修改将被撤销,对其他事务不可见。

4、版本的回收:
**为了防止数据库中的版本无限增长,MVCC 会定期进行版本的回收。**回收机制会删除已经不再需要的旧版本数据,从而释放空间。

MVCC 通过创建数据的多个版本和使用快照读取来实现并发控制。读操作使用旧版本数据的快照,写操作创建新版本,并确保原始版本仍然可用。这样,不同的事务可以在一定程度上并发执行,而不会相互干扰,从而提高了数据库的并发性能和数据一致性。一致性非锁定读和锁定读

一致性非锁定读 和 锁定读

一致性非锁定读与锁定读的区别主要针对的是读操作在加锁方式上的差别。这里先看下锁的分类吧。

一致性非锁定读

一致性非锁定读是InnoDB存储引擎通过多版本控制(multi versioning)的方式来读取当前执行时间数据库中的数据。如果被读的数据行被加了排他锁,在读取这行数据的时候并不会等待锁释放,而是读取该行的一个快照数据。 之所以称为非锁定读,因为不需要等待被访问行的X锁的释放。快照数据是指修改行之前的数据版本,该实现通过undo段来完成。

●非锁定读的方式极大提高了数据库的并发性。在InnoDB存储引擎中,这是默认的读取方式。

快照数据其实就是当前行数据的一个历史版本,每行记录可能有多个版本。这种技术成为多行版本技术。由此带来的并发控制,成为多版本并发控制(Multi Version Concurrency Control,MVCC)。

●在事务的隔离级别,READ COMMITED和REPEATABLE READ(InnoDB存储引擎默认的事物隔离级别)下,对快照数据的定义不同。
注意:

  1. 在READ COMMITTED事务隔离级别下,对于快照数据,非锁定读总是读取被锁定行的最新一份快照数据。而在
  2. REPEATABLE READ事务隔离级别下,对于快照数据,非锁定读总是读取事务开始时的数据版本。

也就是说在READ COMMITTED事务隔离级别下,非锁定读读取到的数据是最新的快照版本数据,也就是可以读到另一个事务已经提交了的快照数据。而在REPEATABLE READ下,只会读到事务开始前的数据。
这也就是为什么在read commited 级别下面, 会出现不可重复读的问题

锁定读

 在默认情况下,InnoDB存储引擎对数据采用的是一致性非锁定读。但是有些情况下为了保证数据逻辑的一致性,需要对SELECT的操作加锁。InnoDB存储引擎对于SELECT语句支持两种一致性的锁定读(locking read)操作。
在锁定读下,读取的是数据的最新版本,这种读也被称为 当前读(current read)。

  1. SELECT …… for update (同时会造成幻读问题)

  2. SELECT …… lock in share mode

 其中,SELECT …… for update对读取的记录加一个X锁(排它锁),其他事务不能对已锁定的行加任何锁。
而SELECT …… lock in share mode 是对读取的记录加一个S锁(共享锁),其他事物可以向被锁定的行加S锁,但是如果加X锁,则会被阻塞。

此外,SELECT …… FOR UPDATE, SELECT …… LOCK IN SHARE MODE必须在一个事物中,当事物提交了,锁也就释放了。因此在使用上诉两句SELECT锁定语句时,务必加上BEGIN,START TRANSACTION 或者SET AUTOCOMMIT=0
   在一致性非锁定读下,即使读取的记录已被其它事务加上 X 锁,这时记录也是可以被读取的,即读取的快照数据。

   上面说了,在 Repeatable Read 下 MVCC 防止了部分幻读,这边的 “部分” 是指在 一致性非锁定读 情况下,只能读取到第一次查询之前所插入的数据(根据 Read View 判断数据可见性,Read View 在第一次查询时生成)。但是!如果是 锁定读,每次读取的都是最新数据,这时如果两次查询中间有其它事务插入数据,就会产生幻读。
InnoDB 在实现Repeatable Read 时,如果执行的是当前读,则会对读取的记录使用 Next-key Lock ,来防止其它事务在间隙间插入数据

MVCC的实现?

   MVCC 的实现依赖于:隐藏字段、Read View、undo log。在内部实现中,InnoDB 通过数据行的 DB_TRX_ID 和 Read View 来判断数据的可见性,如不可见,则通过数据行的 DB_ROLL_PTR 找到 undo log 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改

隐藏字段

在内部,InnoDB 存储引擎为每行数据添加了三个 隐藏字段:
●DB_TRX_ID(6字节):表示最后一次插入或更新该行的事务 id此外,delete 操作在内部被视为更新,只不过会在记录头Record header 中的 deleted_flag 字段将其标记为已删除
●DB_ROLL_PTR(7字节) 回滚指针,指向该行的 undo log 。如果该行未被更新,则为空
●DB_ROW_ID(6字节):如果没有设置主键且该表没有唯一非空索引时,InnoDB 会使用该 id 来生成聚簇索引ReadView

undo-log

undo-log日志中,主要有两个作用
●当事务回滚时用于将数据恢复到修改前的样子
●另一个作用是 MVCC ,当读取记录时,若该记录被其他事务占用或当前版本对该事务不可见,则可以通过 undo log 读取之前的版本数据,以此实现非锁定读

在 InnoDB 存储引擎中 undo log 分为两种:insert undo log 和 update undo log:

  1. insert undo log:
    指在 insert 操作中产生的 undo log。因为 insert 操作的记录只对事务本身可见,对其他事务不可见,故该 undo log 可以在事务提交后直接删除。不需要进行 purge 操作insert 时的数据初始状态:

  2. update undo log:update 或 delete 操作中产生的 undo log。该 undo log可能需要提供 MVCC 机制,因此不能在事务提交时就进行删除。提交时放入 undo log 链表,等待 purge线程 进行最后的删除
    如图
    在这里插入图片描述

在 可重复读 与 串行化 的级别下MVCC的差异?

在事务隔离级别 读已提交 和 可重复读(InnoDB 存储引擎的默认事务隔离级别)下,InnoDB 存储引擎使用 MVCC(非锁定一致性读),但它们生成 Read View 的时机却不同在 读已提交 隔离级别下的 每次select 查询前都生成一个Read View (m_ids 列表)在 RR 隔离级别下只在事务开始后 第一次select 数据前生成一个Read View(m_ids 列表)

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

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

相关文章

基于python的舞蹈经验分享交流网站django+vue

1.运行环境:python3.7/python3.8。 2.IDE环境:pycharmmysql5.7/8.0; 3.数据库工具:Navicat11 4.硬件环境:windows11/10 8G内存以上 5.数据库:MySql 5.7/8.0版本; 运行成功后,在浏览器中输入&am…

Nginx负载均衡主备模式

1. 背景 使用Nginx代理后端服务,有时候某些服务是不能使用多台负载均衡,但又想保障高可用,所以采用主备模式,记录如下: 2. 参考 nginx 负载均衡Nginx-负载均衡-后端状态max_conns、down、backup、max_fails、fail_t…

Docker: 如何不新建容器 修改运行容器的端口

目录 一、修改容器的映射端口 二、解决方案 三、方案 一、修改容器的映射端口 项目需求修改容器的映射端口 二、解决方案 停止需要修改的容器 修改hostconfig.json文件 重启docker 服务 启动修改容器 三、方案 目前正在运行的容器 宿主机的3000 端口 映射 容器…

修改Docker容器内文件的三种方式

说明:本文介绍修改Docker容器内文件的三种方式 方式一:直接修改 敲下面的命令,进入Docker容器,如mysql docker exec -it mysql /bin/bash修改mysql的配置文件,/etc/my.cnf vim /etc/my.cnf如下,如果vim…

【机器学习】基于扩散模型的文本到音频生成:突破数据局限,优化音频概念与实践顺序

基于扩散模型的文本到音频生成:突破数据局限,优化音频概念与时间顺序 一、现有模型的局限与挑战二、偏好数据集的构建与利用三、Diffusion-DPO损失的应用与模型微调四、实例与代码展示五、总结与展望 随着数字化技术的迅猛发展,音乐和电影行业…

霍纳法则与多项式求值问题

目录 多项式求值问题引入 什么是霍尔法则 多项式求值问题引入 题目链接:多项式求值 对于多项式求值问题,例如多项式: 常规的计算方法是每一项单独计算,即先计算,再接着计算,以此类推,最后求和即可&…

排序-八大排序FollowUp

FollowUp 1.插入排序 (1).直接插入排序 时间复杂度:最坏情况下:0(n^2) 最好情况下:0(n)当数据越有序 排序越快 适用于: 待排序序列 已经基本上趋于有序了! 空间复杂度:0(1) 稳定性:稳定的 public static void insertSort(int[] array){for (int i 1; i < array.length; i…

鸿蒙学习1概况

鸿蒙学习1相关概念 前言相关概念Stage 模型1. AbilityStage2. UIAbility组件和ExtensionAbility组3. WindowStage4. Context 事件传递UIAbility组件与UI的数据同步UIAbility组件间交互&#xff08;设备内&#xff09; 进程模型线程模型 前言 有时间多看官网&#xff0c;官网的…

Android项目中添加Dobby(inline hook)

2024技术交流群 ​ 课程地址 鸿蒙(HarmonyOS)APP开发实战课程(入门到精通) https://edu.csdn.net/course/detail/39448 1.Ubuntu编译Dobby 2.Dobby框架的介绍 Dobby是一个轻量级、多平台、多架构的inline hook框架&#xff0c;它使用起来轻快便捷&#xff0c;支持Windows/ma…

git如何将多个commit合并成一个?

我们使用git进行版本控制&#xff0c;在本地开发完某个功能时&#xff0c;需要提交commit&#xff0c;然后push至开发分支。简单的功能还好&#xff0c;几个commit可能就好了。但是如果功能比较复杂&#xff0c;commit多达十几甚至几十个时&#xff0c;commit管理就会很冗长。比…

selinux 基础知识

目录 概念 作用 SELinux与传统的权限区别 SELinux工作原理 名词解释 主体&#xff08;Subject&#xff09; 目标&#xff08;Object&#xff09; 策略&#xff08;Policy&#xff09; 安全上下文&#xff08;Security Context&#xff09; 文件安全上下文查看 先启用…

【数据结构】二叉树(带图详解)

文章目录 1.树的概念1.2 树的结构孩子表示法孩子兄弟表示法 1.3 相关概念 2.二叉树的概念及结构2.1 二叉树的概念2.2 数据结构中的二叉树-五种形态2.3 特殊的二叉树2.4 二叉树的存储结构顺序存储链式存储 2.5 二叉树的性质 3. 堆3.1 堆的定义3.2 堆的实现堆的结构堆的插入向上调…

Android binder死亡通知机制

在Andorid 的binder系统中&#xff0c;当Bn端由于种种原因死亡时&#xff0c;需要通知Bp端&#xff0c;Bp端感知Bn端死亡后&#xff0c;做相应的处理。 使用 Bp需要先注册一个死亡通知&#xff0c;当Bn端死亡时&#xff0c;回调到Bp端。 1&#xff0c;java代码注册死亡通知 …

Springboot+Vue+小程序+基于微信小程序护农远程看护系统

开发平台为idea&#xff0c;maven管理工具&#xff0c;Mybatis操作数据库&#xff0c;根据市场数字化需要为农户打造小程序可远程查看农场的种植情况。项目是调试&#xff0c;讲解服务均可有偿获取&#xff0c;需要可在最下方QQ二维码处联系我。 SpringbootVue小程序&#xff…

Android --- 消息机制与异步任务

在Android中&#xff0c;只有在UIThread(主线程)中才能直接更新界面&#xff0c; 在Android中&#xff0c;长时间的工作联网都需要在workThread(分线程)中执行 在分线程中获取服务器数据后&#xff0c;需要立即到主线程中去更新UI来显示数据&#xff0c; 所以&#xff0c;如…

50. 【Android教程】xml 数据解析

xml 是一种标记扩展语言&#xff08;Extension Mark-up Language&#xff09;&#xff0c;学到这里大家对 xml 语言一定不陌生&#xff0c;但是它在 Android 中的运用其实只是冰山一角。抛开 Android&#xff0c;XML 也被广泛运用于各种数据结构中。在运用 xml 编写 Android 布…

Docker创建镜像之--------------基于Dockerfile创建

目录 一、在编写 Dockerfile 时&#xff0c;有严格的格式需要遵循 二、Dockerfile 操作常用的指令 2.1ENTRYPOINT和CMD共存的情形 2.2ENTRYPOINT和CMD的区别 2.3ADD 与COPY的区别 三、Dockerfile案例 3.1构建apache镜像 3.1.1 创建镜像目录方便管理 3.1.2创建编写dock…

基于Springboot的音乐翻唱与分享平台

基于SpringbootVue的音乐翻唱与分享平台设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 音乐资讯 音乐翻唱 在线听歌 后台登录 后台首页 用户管理 音乐资讯管理…

基础安全:CSRF攻击原理与防范

CSRF的概念 CSRF(Cross-Site Request Forgery)中文名为“跨站请求伪造”。这是一种常见的网络攻击手段,攻击者通过构造恶意请求,诱骗已登录的合法用户在不知情的情况下执行非本意的操作。这种攻击方式利用了Web应用程序中用户身份验证的漏洞,即浏览器在用户完成登录后会自…

JavaEE 初阶篇-深入了解网络原理中传输层的端口号与 UDP 协议报文格式

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 端口号概述 1.1 端口号的作用 1.2 端口号不能重复被多个进程绑定 2.0 传输层协议 - UDP 2.1 UDP 的特性 2.2 UDP 的报文格式 1.0 端口号概述 端口号是计算机网络中…