当前位置: 首页 > article >正文

Mysql-事务(Transaction)详解

什么是事务?

        事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行。

特点:

        一个事务中如果有一个数据库操作失败,那么整个数据库的所有操作都会失败,数据库数据就会回滚到该事务开始之前的状态。

限制:

        MySQL数据库中仅InnoDBBDB类型的数据库表支持事务。

事务的ACID原则

1. 原子性(Atomic)

意味着数据库中的事务执行是作为原子粒度。即不可再分,整个语句要么执行,要么不执行。

2. 一致性(Consist)

即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

3. 隔离型(Isolated)

事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。

4. 持久性(Durable)

意味着在事务完成以后 ,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

Mysql事务实现

方法

  • START TRANSACTION开始一个事务,标记事务的起始点
  • SET AUTOCOMMIT:使用该语句来改变自动提交模式,等于0时关闭自动提交模式,等于1时开启自动提交模式。默认为1,使用事务时为0
  • COMMIT:提交一个事务给数据库
  • ROLLBACK:将事务回滚,数据回到本次事务的初始状态

步骤

  1. 关闭MySQL自动提交:SET AUTOCOMMIT = 0
  2. 开启一个事务,标记事务的起始点:START TRANSACTION;
  3. 提交或者回滚(只能存在其一)
    1. 提交:COMMIT
    2. 回滚:ROLLBACK
  1. 开启MySQL自动提交:SET AUTOCOMMIT = 1

事务的原子性,一致性,持久性

事务的原子性、一致性和持久性由事务的 redo 日志和undo 日志来保证。

  • REDO LOG :称为 重做日志 ,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。
  • UNDO LOG :称为 回滚日志 ,回滚行记录到某个特定版本,用来保证事务的原子性、一致性

事务的隔离性

        事务的隔离性是指为了让不同的事务之间相互不存在干扰,就需要对事务的操作进行隔离,事务的隔离性也就是将操作同一个数据的事务相互分离,让操作之间分开有序的执行。

用什么方式实现事务的隔离性

        通常数据库里都是采用锁的机制,保证事务之间的隔离性

Mysql中的锁

表级锁(Table Locks)

        表级锁是锁定整个表的锁。这种锁开销较小,但并发性较差。表级锁分为两类:

  • 表共享读锁(Table Read Lock, S锁): 允许其他事务读取,但不允许写入
  • 表独占写锁(Table Write Lock, X锁): 不允许其他事务读取和写入
行级锁(Row Locks)

        行级锁是锁定表中的具体行。这种锁开销较大,但并发性好。行级锁在InnoDB存储引擎中最为常见,并分为两类:

  • 共享锁(Shared Lock, S锁):允许事务读取一行,但不允许修改。
  • 排他锁(Exclusive Lock, X锁):允许事务读取和修改一行。
全局锁(Global Locks):

        全局锁用于锁定整个数据库实例,通常用于备份。MySQL提供了FLUSH TABLES WITH READ LOCK (FTWRL)命令来实现全局锁。

元数据锁(Meta-data Lock, MDL)

        MDL用于保护表的元数据不被并发修改。当一个事务正在访问表元数据(如修改表结构)时,其他事务必须等待,以确保元数据的一致性。

意向锁(Intention Lock)

        意向锁是一种表级锁,表示事务希望在表中的某些行上设置行级锁。意向锁分为两类:

  • 意向共享锁(Intention Shared Lock, IS锁):表示事务准备设置共享锁。
  • 意向排他锁(Intention Exclusive Lock, IX锁):表示事务准备设置排他锁。
记录锁(Record Lock)

        记录锁是行级锁的一种,锁定索引记录。

间隙锁(Gap Lock)

        间隙锁锁定索引记录之间的间隙,防止其他事务在这些间隙中插入新记录。主要用于防止幻读现象。

临键锁(Next-Key Lock)

        临键锁是记录锁和间隙锁的组合,锁定索引记录及其前面的间隙。这种锁在InnoDB的可重复读(REPEATABLE READ)隔离级别下用于防止幻读。

插入意向锁(Insert Intention Lock)

        插入意向锁是一种特殊的间隙锁,用于在间隙中插入新记录。多个事务可以在同一个间隙中持有插入意向锁,而不会互相阻塞。

事务并发时出现的问题

1. 脏写

        当两个或多个事务同时修改同一数据时,后提交的事务可能会覆盖前一个事务所做的修改,导致前一个事务的更新被丢失。

2. 脏读(可重复读)

        一个事务读取了另一个事务尚未提交的数据。如果后续这个事务被回滚,那么读取到的数据就是无效的。

3. 不可重复读

在同一个事务中,两次读取同一行数据得到的结果不一致。

  • 并发事务更新:当一个事务在读取数据后,另一个事务对同一行数据进行了更新操作。
  • 并发事务删除:当一个事务在读取数据后,另一个事务对同一行数据进行了删除操作。

4. 幻读

在同一个事务中,两次查询相同条件的数据得到的结果集不一致。

  • 并发事务插入:当一个事务在查询数据后,另一个事务对相同的条件的数据进行了插入操作。
  • 并发事务删除:当一个事务在查询数据后,另一个事务对相同的条件的数据进行了删除操作。
  • 并发事务更新:当一个事务在查询数据后,另一个事务对相同条件的数据进行了更新操作。

事务的隔离级别

1. 读未提交:

  • 事务读取:不加锁
  • 事务写入:加写锁
  • 解决问题:脏写
  • 存在问题:脏读,不可重复读,幻读

2. 读提交(不可重复读):

  • 事务读取:加读锁(每次select完释放读锁)
  • 事务写入:加写锁
  • 解决问题:脏写,脏读
  • 存在问题:不可重复读,幻读

3. 可重复读:

  • 事务读取:加读锁(每次select完不释放锁,而是事务结束后才释放)(如果是mysql的InnoDB还会加间隙锁)
  • 事务写入:加写锁
  • 解决问题:脏写,脏读,不可重复读
  • 存在问题:幻读(InnoDB不存在幻读)

4. 串行化:

        事务之间没有影响,不管读取还是修改事务,串行化执行,一个事务执行必须等其他事务结束

InnoDB的MVCC

        MVCC 的实现依赖于:隐藏字段(版本号)、Undo Log、Read View。

        MVCC (Multiversion Concurrency Control),多版本并发控制。顾名思义,MVCC 是通过数据行的多个版本管理来实现数据库的 并发控制 。这项技术使得在InnoDB的事务隔离级别下执行 一致性读 操作有了保证。换言之,就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值,这样 在做查询的时候就不用等待另一个事务释放锁。

InnoDB就是通过MVCC机制解决可重复读中的幻读问题


http://www.kler.cn/news/359892.html

相关文章:

  • pod相关面试题总结(持续更新)
  • 【ARM】ARM架构参考手册_Part A CPU(1)
  • 【BUG】解决已安装anaconda的pycharm中jupyter服务器中出现的import jieba失败问题
  • SpringBoot启动报错java.nio.charset.MalformedInputException: Input length =1
  • SAP揭秘者-怎么查看SAP 版本及S4 HANA的版本
  • 开启RefCell debug_refcell feature查看借用冲突位置
  • PCL 基于中值距离的点云对应关系
  • linux模拟:chrony同步时间
  • 信创:推动信息技术应用创新的国产化之路
  • react18中在列表中如何使用useCallback进行渲染优化
  • 大模型的检索增强生成综述研究
  • 利用TLP185光耦合器增强电路隔离和信号完整性
  • (AtCoder Beginner Contest 375) 题解(下)
  • 408 10——42题
  • [英语单词] sk_under_memory_pressure
  • MySQL 初阶——多版本控制 MVCC
  • Tkinter -- python GUI学习与使用
  • 1.前提配置 关防火墙 关selinux
  • 每日一题|910.最小差值II|数组排序思路、单调性
  • 深入理解Python函数