洛阳市网站建设_网站建设公司_HTTPS_seo优化
2025/12/23 2:04:10 网站建设 项目流程

Mysql事务

1、事务的ACID模型(事务四大特性)

1. 原子性(Atomicity):“要么全做,要么全不做”

事务是不可分割的最小操作单元,所有操作要么全部成功,要么全部失败

是最小的不可分割的操作单元。要么所有操作都执行成功并提交(Commit),要么所有操作都执行失败并回滚(Rollback),不存在 “部分执行” 的中间状态。

2. 一致性(Consistency):“事务前后,数据状态合法”

事务完成时,必须使所有的数据都保持一致状态

事务完成时,必须使所有的数据都保持一致,即保证事务前后数据的完整性和一致性。数据从一个 “合法状态” 转换到另一个 “合法状态”,不会出现逻辑矛盾的数据。

3. 隔离性(Isolation):“事务之间互不干扰”

数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行

多个事务并发执行时,每个事务的执行过程应 “看不到” 其他事务的中间状态,即一个事务的操作结果,要么在其他事务提交后可见,要么在其他事务开始前可见,避免并发导致的数据混乱

数据库系统提供的隔离机制,通过不同的隔离级别,保证事务在不受外部并发操作影响的独立环境下运行。

4. 持久性(Durability):“事务提交后,结果永久保存”

事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

事务一旦提交,其对数据的修改就会永久保存到数据库中,即使机器发生故障或数据库崩溃(如断电、磁盘损坏),修改结果也不会丢失。可以通过日志等方式恢复数据。

2、并发下的事务问题

在数据库实际运行中,单事务执行场景极少,更多是多个事务同时操作相同或相关数据(即 “事务并发”)。若缺乏有效的隔离机制,事务并发会破坏数据的一致性,导致多种典型问题。这些问题的本质是:并发事务的 “操作交叉执行”,使得一个事务能感知到另一个事务的 “中间未提交状态” 或 “已提交的修改结果”,进而引发数据逻辑矛盾。

1、脏读:一个事务读取到另一个事务还没有提交的数据。

一个事务(事务 A)读取了另一个事务(事务 B)尚未提交的修改数据,若后续事务 B 因错误回滚(Rollback),事务 A 之前读取的数据就成了 “无效的脏数据”,基于脏数据的业务决策会完全错误。

2、不可重复读:一个事务先后读取同一条记录,但是两次读取的数据不同,本质就是读取到了其他事务提交的数据。

同一个事务(事务 A)在多次读取同一行数据的过程中,另一个事务(事务 B)对该数据执行了 “修改并提交” 操作,导致事务 A 前后两次读取的结果不一致(“不可重复”)。

不可重复读,没有违反读已提交,但违反了“可重复读(Repeatable Read)”及以上级别的隔离要求

3、幻读:在解决不可重复读的前提下,一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了一个幻影,再次查询又查不到。

同一个事务(事务 A)在多次执行相同的 “范围查询”(如 “查询余额> 500 的用户”)时,另一个事务(事务 B)对该查询范围内的数据执行了 “插入 / 删除并提交” 操作,导致事务 A 前后两次查询的“结果行数” 不一致(像出现了 “幻觉” 一样的新增 / 消失数据)。

3、事务的隔离级别(解决并发事务的问题):

事务的隔离级别是数据库管理并发事务之间数据可见性的规则,它决定了一个事务中的修改何时对其他事务可见。

1、Read uncommitted(读未提交):什么并发事务问题都不能解决。(读未提交,可以读到其他事务尚未提交的数据)这是最低的隔离级别,允许一个事务读取另一个事务未提交的修改。

2、Read committed(读已提交):这是大多数数据库系统的默认隔离级别(如 Oracle、SQL Server),确保一个事务只能看到其他事务已提交的修改。

只能解决脏读。(读已提交,只读其他事务已经提交的数据,不能读取未提交的更改,原因就是:在读取数据时加入了共享锁(错误),但是,只是在读取时暂时,在事务提交或回滚后,就会释放锁,从而解决脏读问题)

3、Repeatable Read(可重复读)

这是MySQL InnoDB 的默认隔离级别,确保同一事务中多次读取同一数据时,结果始终一致,不受其他事务提交的修改影响。

只解决脏读、不可重复读。(会在整个事务期 间持有锁,解决脏读和不可重复读)

实现原理:通过MVCC实现,事务启动时创建数据快照,整个事务过程中都使用这个快照,不受其他事务

影响。

4、Serializable(串行化)

这是最高的隔离级别,强制事务串行执行,避免了所有并发问题。

所有的都能解决。(会对查询的范围加范围锁,并且事务会按照一定的顺序排队执行,不会出现并发问题)

实现原理:通常通过表级锁实现,一个事务操作表时会锁定整个表,阻止其他事务操作。

4、事务的原理:日志与隔离机制的协同运作

事务的 ACID 特性并非凭空实现,而是依赖于数据库底层精心设计的技术架构。

其中原子性、一致性、持久性主要通过redo log(重做日志)undo log(回滚日志)保证,

而隔离性则由锁机制MVCC(多版本并发控制共同支撑。这些机制相互配合,构成了事务可靠性的基础。

1、基本概述
  • 原子性、一致性、持久性:是通过底层的两个日志文件来实现的,redo log 、undo log
  • 是通过底层的两个日志文件来实现的,redo log 、undo log
  • 隔离性:是通过锁机制和MVCC(多版本并发控制)来实现的。
2、详细解释
  • 持久性
    • 利用redo log(重做日志)实现。重做日志,记录事务提交时的数据物理页修改,即,redo log记录的是,某个页的某个数据从什么值变成什么值
    • 该日志主要分为两个部分
      • 重做缓冲日志redo log buffer,存在于内存中,记录事务提交时的物理修改。
      • 重做日志文件redo log file,存在于磁盘中。
    • 过程:当对缓冲区的数据进行增删改之后,会首先将数据页的变化记录到redo log buffer中,在事务提交后,会直接redo log buffer中的数据刷新到磁盘的redo log file中,之后当脏页刷新到磁盘时出错了,就可以通过redo log file来进行恢复。
    • 注意:为什么不在事务提交的时候直接将脏页刷新到磁盘,而是通过redo log来实现,因为,直接刷新存在严重的性能问题。一个事务中,可能包含多条sql,即使是一条sql也可能涉及多个数据页,每条语句的数据不一定相同,会涉及到很多随机磁盘IO,而log都是追加的,因此是顺序磁盘IO,顺序 IO 的效率大于随机 IO

  • 原子性
    • undo log(回滚日志)用于回滚日志,记录数据被修改前的信息,作用包含两个:提供回滚和MVCC(多版本并发控制)
    • undo log逻辑日志。可以认为当delete一条记录时,undo log会记录一条对应的 insert 记录,反之亦然,当update一条记录时,他记录一条对应相反的update记录。当执行rollback时,就可以从undo log中的逻辑记录中读取到相应的内容,并进行回滚,从而保证数据的原子性(主要是回滚),实际上就是记录旧版本的数据
      • 销毁:undo log在事务执行时产生,事务提交时,并不会立即删除,因为这些事务有可能涉及到MVCC
      • 存储:undo log采用段的方式进行管理和记录,存放在rollback segament回滚段中。内部包含1024个undo log segment

为什么说MVCC + 锁,保证事务的隔离性?

一、MVCC 负责 “读操作” 的隔离性:避免读 - 写冲突

MVCC 通过维护数据的多版本快照,让读操作可以读取历史版本,无需加锁,从而避免了 “读阻塞写、写阻塞读” 的情况,同时保证了不同隔离级别下的读一致性。

  • 读已提交(RC):每次读生成新的快照(ReadView),只读取已提交的最新版本,避免脏读,保证 “读已提交” 的隔离性。
  • 可重复读(RR,默认):事务启动时生成全局快照,整个事务内读同一版本,避免不可重复读和幻读(结合间隙锁),保证 “可重复读” 的隔离性。

二、锁机制负责 “写操作” 的隔离性:避免写 - 写冲突

锁机制通过对数据加排他锁或共享锁,保证写操作的原子性和一致性,防止多个事务同时修改同一数据。

  • 行级锁(排他锁)UPDATEDELETE等写操作会对目标行加排他锁,其他事务无法同时修改该行,避免 “脏写”。
  • 间隙锁 / Next-Key Lock(RR 级别):在可重复读隔离级别下,通过锁定记录间隙,防止其他事务插入新记录,避免 “幻读”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询