MySQL基础事务机制第9章揭秘

MySQL基础事务处理的第九篇章剖析

标题:[MySQL入门]MySQL(9)事务机制概览
@墨白不码错

在这里插入图片描述


文章目录

  • 一、认识事务
    • 1、多线程访问数据库引发的状况
    • 2、通过事务机制限制CURD操作
    • 3、事务的四大特性
    • 4、支持事务的引擎
  • 二、事务的提交与autocommit设置
  • 三、事务的隔离性与隔离级别
    • (1) 查看当前隔离级别
    • (2) 设置隔离级别
    • (3) 事务隔离级别的作用
    • (4)MySQL InnoDB的四种隔离级别
    • (1) 读未提交(Read Uncommitted)
    • (2) 读已提交(Read Committed)
    • (3) 可重复读(Repeatable Read)
    • (4) 串行化(Serializable)
    • (5)各隔离级别对比表
  • 四、事务的一致性
      • 1. AID特性和一致性的关联
      • (1) 原子性(Atomicity)
      • (2) 隔离性(Isolation)
      • (3) 持久性(Durability)
      • (4) 应用层面的逻辑(用户的协同)

一、认识事务

1、多线程访问数据库引发的状况

MySQL作为网络服务,必然存在多个客户端同时访问服务器的情形:设想有一个抢票系统,两个客户端同时抢票,其中一个客户端完成抢票操作后,数据库尚未及时更新,此时另一客户端又进行了抢票,导致一张票被重复售卖,这显然不符合正常逻辑!因此,必须对数据库的CURD操作实施特定限制,以此解决此类问题。

2、通过事务机制限制CURD操作

事务由一组具有逻辑关联性的DML语句构成,这些语句要么全部成功执行,要么全部失败回滚,形成一个整体。事务常用于处理操作量大、复杂度高的数据。例如,要删除一位被开除员工的所有历史信息及相关联信息,需多条MySQL语句协同完成,这些操作共同构成一个事务。

然而,同一时刻并非仅有一个事务在运行,而是有多个事务并发执行。若大量事务在无保护的情况下访问同一表数据,必然引发问题。因为事务由多条SQL语句组成,若事务执行中途MySQL客户端异常退出,已执行一半的事务该如何处理?

3、事务的四大特性

MySQL规定,一个完整的事务不仅是简单SQL语句的组合,还需满足以下四大特性:

原子性(Atomicity,也可称为不可分割性):
一个事务(transaction)内的所有操作,要么完全执行完毕,要么完全不执行,不会停留在中间状态。若事务执行过程中出现错误(比如客户端异常退出),已执行一半的事务会被回滚至事务开始前的状态,仿佛该事务从未执行过。

一致性(Consistency):
在事务开启前和结束后,数据库的完整性均未遭到破坏。

隔离性(Isolation,也称作独立性):
数据库支持多个并发事务同时对数据进行读写与修改,隔离性能够避免多个事务并发执行时因交叉执行而致使数据不一致。事务隔离涵盖不同级别,包含读未提交(Read uncommitted)、读已提交(read committed)、可重复读(repeatable read)以及串行化(Serializable)。

持久性(Durability):
事务处理完成后,对数据的改动会永久保存,即便系统发生故障也不会丢失。

此外,事务本质上是为应用层服务的。因为我们并非直接访问数据库,而是通过上层各种语言来访问数据库,所以多条SQL语句封装而成的事务能够简化上层的编程模型与逻辑。

4、支持事务的引擎

使用指令查询:

mysql> show engines\G;
*************************** 1. row ***************************
          Engine: ndbcluster
         Support: NO
         Comment: Clustered, fault-tolerant tables
    Transactions: NULL
              XA: NULL
      Savepoints: NULL
*************************** 2. row ***************************
          Engine: MEMORY
         Support: YES
         Comment: Hash based, stored in memory, useful for temporary tables
    Transactions: NO
              XA: NO
      Savepoints: NO
*************************** 3. row ***************************
          Engine: InnoDB
         Support: DEFAULT
         Comment: Supports transactions, row-level locking, and foreign keys
    Transactions: YES
              XA: YES
      Savepoints: YES
*************************** 4. row ***************************
          Engine: PERFORMANCE_SCHEMA
         Support: YES
         Comment: Performance Schema
    Transactions: NO
              XA: NO
      Savepoints: NO
*************************** 5. row ***************************
          Engine: MyISAM
         Support: YES
         Comment: MyISAM storage engine
    Transactions: NO
              XA: NO
      Savepoints: NO
*************************** 6. row ***************************
          Engine: FEDERATED
         Support: NO
         Comment: Federated MySQL storage engine
    Transactions: NULL
              XA: NULL
      Savepoints: NULL
*************************** 7. row ***************************
          Engine: ndbinfo
         Support: NO
         Comment: MySQL Cluster system information storage engine
    Transactions: NULL
              XA: NULL
      Savepoints: NULL
*************************** 8. row ***************************
          Engine: MRG_MYISAM
         Support: YES
         Comment: Collection of identical MyISAM tables
    Transactions: NO
              XA: NO
      Savepoints: NO
*************************** 9. row ***************************
          Engine: BLACKHOLE
         Support: YES
         Comment: /dev/null storage engine (anything you write to it disappears)
    Transactions: NO
              XA: NO
      Savepoints: NO
*************************** 10. row ***************************
          Engine: CSV
         Support: YES
         Comment: CSV storage engine
    Transactions: NO
              XA: NO
      Savepoints: NO
*************************** 11. row ***************************
          Engine: ARCHIVE
         Support: YES
         Comment: Archive storage engine
    Transactions: NO
              XA: NO
      Savepoints: NO
11 rows in set (0.01 sec)

从查询结果可知,目前仅有InnoDB引擎支持事务机制


二、事务的提交与autocommit设置

事务的提交(commit)方式存在两种:
自动提交模式;
手动提交模式;
autocommit变量用于设定是否开启自动提交。
查看autocommit变量:

show variables like 'autocommit';

设置自动提交状态:

SET AUTOCOMMIT=1; #SET AUTOCOMMIT=1 开启自动提交功能
SET AUTOCOMMIT=0; #SET AUTOCOMMIT=0 关闭自动提交功能

若要开启一个事务,需使用以下指令:

begin;
#或者
start transaction;

若要提交一个事务,需使用指令:

commit;

这两个指令之间的SQL语句即为该事务的具体内容。


为便于后续演示,创建如下表结构:

create table if not exists account(
    id int primary key,
    name varchar(50) not null default '',
    blance decimal(10,2) not null default 0.0
    )ENGINE=InnoDB DEFAULT CHARSET=UTF8;

此时暂时将全局隔离级别设置为读未提交(以便通过另一客户端查看表中数据):

set global transaction isolation level READ UNCOMMITTED;

查看隔离级别:

SELECT @@global.transaction_isolation AS '全局隔离级别', @@session.transaction_isolation AS '当前会话隔离级别';

重启MySQL,同步当前会话与全局的隔离级别后查看:
在这里插入图片描述

  • 特性一 :若事务通过begin/start transation方式开启,则必须通过commit提交才能持久化,这与autocommit设置无关(默认情况下autocommit为ON开启状态,具体作用后文讲解)。

若有两个客户端同时访问同一张表,且同时开启两个事务,其中一个客户端事务执行至一半时崩溃,MySQL会自动回滚


何为回滚?
当开启一个事务后,在事务执行过程中,可创建保存点,此保存点可类比为游戏中的存档点,若对最新操作不满意,可回滚(读取存档点):

savepoint s1; #创建一个保存点s1

首先,通过begin;开启一个事务。
然后,向已创建的表中插入数据:
在这里插入图片描述
此时设置一个savepoint s1;
在这里插入图片描述
接着进行一些增删改操作(例如新插入一条数据):
在这里插入图片描述
若发现新进行的操作出现错误且不想要该结果,可回滚(读取存档点s1):

rollback to s1;

结果:
在这里插入图片描述
于是,新插入的“haha”数据被删除。这便是回滚


回归特性一的演示:
验证:未commit,客户端崩溃,MySQL自动回滚[因通过手动开启,autocommit不会自动提交]
开启两个事务,左侧插入一条新数据lisi,右侧可看到新插入的数据:

在这里插入图片描述
左侧事务的客户端被ctrl+\发送abort信号,进程被杀死,右侧客户端发现新插入的lisi被MySQL自动回滚。
在这里插入图片描述

验证:commit后,客户端崩溃,MySQL数据不受影响,已持久化[因通过手动开启,autocommit不会自动提交]

开启两个事务,左侧客户端插入数据jimmay,commit后被信号杀死,右侧查询可找到新插入的数据:
在这里插入图片描述

验证:未手动通过begin;/start transaction;开启事务,autocommit会影响提交。

在autocommit=1;(开启)情况下:
对于未手动通过begin;/start transaction;开启事务的情况,一条SQL语句即为一个事务,因为每条语句都会被封装为一个事务。
即使一条语句执行后客户端直接崩溃,该语句仍会被持久化:
在这里插入图片描述
在autocommit=0;(开启)情况下:
需手动commit,无论执行多少操作,若在客户端退出前未commit,则所有操作均会被回滚:
在这里插入图片描述
若commit,所做操作会被持久化:
在这里插入图片描述


至此,可总结如下:

  • 事务通过begin/start transaction开启,需手动commit提交才能持久化,不受autocommit设置影响。
  • 事务可通过设置savepoint手动回滚;操作异常时,MySQL会自动回滚。
  • InnoDB每条SQL语言默认封装成事务,自动提交。(select有特殊情况,因MySQL有MVCC)。
  • 从上述演示,可见事务本身的原子性(回滚)、持久性(commit)。

隔离性体现在何处?


三、事务的隔离性与隔离级别

数据库中,为保证事务执行过程中尽可能不受干扰,存在重要特性:隔离性
数据库中,允许事务受不同程度干扰,存在重要特性:隔离级别

(1) 查看当前隔离级别

SHOW VARIABLES LIKE 'transaction_isolation';
-- 输出示例:transaction_isolation = REPEATABLE-READ

(2) 设置隔离级别

-- 全局设置(重启后生效)
SET GLOBAL TRANSACTION ISOLATION LEVEL+隔离级别值;
-- 当前会话设置
SET SESSION TRANSACTION ISOLATION LEVEL+隔离级别值;

MySQL InnoDB存储引擎支持四种标准事务隔离级别,通过不同锁机制多版本并发控制(MVCC) 实现事务间数据可见性与并发控制。


(3) 事务隔离级别的作用

事务隔离级别定义了多个并发事务间的数据可见性规则,核心目标是解决以下问题:

  • 脏读(Dirty Read) :读取到其他事务未提交的数据。
  • 不可重复读(Non-Repeatable Read) :同一事务中多次读取同一数据,结果不一致(其他事务修改了该行)。
  • 幻读(Phantom Read) :同一事务中,因其他事务插入或删除符合查询条件的行,导致多次相同查询的结果集行数不一致。

(4)MySQL InnoDB的四种隔离级别

按隔离级别从低到高排序:

(1) 读未提交(Read Uncommitted)

  • 特点 :所有事务均可看到其他事务未提交的数据
    执行结果(可能读到“脏数据”)相当于无任何隔离性。

  • 问题 :存在 脏读、不可重复读、幻读

  • 实现方式 :几乎不加锁,依赖最低限度的锁机制。
  • 使用场景 :极少使用,仅在需最高并发且不关心数据一致性的场景。

(2) 读已提交(Read Committed)

  • 特点 :一个事务只能看到其他已提交事务所做的改变。
  • 解决的问题 :避免脏读。
  • 遗留问题 :存在 不可重复读、幻读
  • 实现方式
    • 锁机制 :使用 行级锁(Record Locks) ,写操作锁定当前行。
    • MVCC :每次 SELECT 生成独立快照(一致性视图),基于当前已提交数据。
  • 使用场景 :适用于大多数OLTP系统(如Oracle默认级别)。

(3) 可重复读(Repeatable Read)

  • 特点 :MySQL默认隔离级别,同一事务中多次读取同一数据结果一致。
  • 解决的问题 :避免脏读、不可重复读。
  • 遗留问题 :仍可能发生 幻读 (但InnoDB通过 间隙锁 基本消除)。
  • 实现方式
    • 锁机制 :使用 记录锁(Record Locks) + 间隙锁(Gap Locks) (合称 临键锁 Next-Key Locks )。
    • MVCC :事务首次 SELECT 生成一致性视图,后续读取沿用该视图。
  • 默认级别 :InnoDB的默认隔离级别。
  • 幻读的解决
    -- 事务A
    BEGIN;
    SELECT * FROM users WHERE age > 20; -- 假设返回3条记录
    
    -- 事务B
    INSERT INTO users (id, age) VALUES (4, 25); -- 提交
    
    -- 事务A再次查询
    SELECT * FROM users WHERE age > 20; -- 在可重复读下,仍返回3条记录(避免幻读)
    

(4) 串行化(Serializable)

*

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/12632.html

(0)
LomuLomu
上一篇 2025 年 6 月 25 日
下一篇 2025 年 6 月 25 日

相关推荐

  • 2025年最新DataGrip激活码与永久破解教程(支持2099年)

    本教程适用于JetBrains全家桶所有产品,包括DataGrip、PyCharm、IDEA等数据库开发工具! 先展示最新DataGrip版本成功激活的截图效果,可以看到已经完美破解到2099年,运行非常稳定! 下面通过详细的图文步骤,手把手教你如何永久激活DataGrip至2099年。 这个方法适用于所有DataGrip版本,包括最新版和历史版本! 支持W…

    DataGrip激活码 2025 年 8 月 14 日
    12900
  • 架构-初识BFF

    引言 晚上公司开了一个技术分享会,主要内容就是公司的项目架构,会中讲解了项目整体架构是BFF架构,就是在微服务之上多加了一层。 除此之外,还讲解了DDD设计思想,主要用于各个业务中台,如订单中台、用户中台等。 这是我的架构第一课,听得有些似懂非懂,于是浅浅地整理一下。 BFF 是什么 BFF是服务于前端的后端,全称Backend For Frontend。B…

    2025 年 1 月 1 日
    35700
  • 算法领域里BFS的应用:最短路径及拓扑排序剖析

    BFS在算法中的应用:最短路径与拓扑排序解析 目录 边权为1的最短路径问题 多源BFS最短路问题 BFS解决拓扑排序 有向无环图(DAG图) AOV网:顶点活动图 拓扑排序 实现拓扑排序 前言 大家好呀!今天为大家带来关于最短路径以及拓扑排序的相关内容,欢迎大家关注、点赞、收藏并留言交流哦。 边权为1的最短路径问题 当所有边的权重都相同时,这类情况可视为边权…

    2025 年 7 月 25 日
    14800
  • Java中List排序的3种方法

    在我们程序的编写中,有时候我们需要在 Java 程序中对 List 集合进行排序操作。比如获取所有用户的列表,但列表默认是以用户编号从小到大进行排序的,而我们的系统需要按照用户的年龄从大到小进行排序,这个时候,我们就需要对 List 集合进行自定义排序操作了。 List 排序的常见方法有以下 3 种: 使用 Comparable 进行排序; 使用 Compa…

    2024 年 12 月 30 日
    52800
  • 如何解决 java.lang.NoClassDefFoundError: 找不到类定义错误?亲测有效的解决方法!

    java.lang.NoClassDefFoundError 是 Java 中的一个常见错误,通常表示 Java 虚拟机(JVM)在运行时无法找到指定的类定义。这个错误的发生通常意味着编译时存在的类在运行时不可用,或者运行时的类路径(classpath)配置不正确。 1. 问题分析 NoClassDefFoundError 错误发生的常见原因有以下几种: 类…

    未分类 2024 年 12 月 30 日
    28900

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信