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
上一篇 10小时前
下一篇 8小时前

相关推荐

  • Redis 爆高危漏洞,请速度修复。。

    大家好,我是R哥。 今天一早收到了腾讯云给我的【主机安全 】漏洞通知: 好家伙,大名鼎鼎的 Redis 爆高危漏洞了,R哥的题库「Java面试库」也用到了 Redis 来缓存面试题内容,所以这一下子就引起了我的警惕,赶紧看看什么鬼。 漏洞描述 下面是漏洞描述和修复说明: https://github.com/redis/redis/security/advi…

    2025 年 1 月 6 日
    29200
  • Python 潮流周刊#80:Django 项目性能调优(摘要)

    由 Python猫 精心策划,本周刊汇集了全球精选的 250+ 资讯,为你呈现最有价值的文章、教程、开源项目、软件工具、音视频内容以及热门话题。我们的目标是助力每一位读者提升 Python 技能,并在职业和副业中实现收入增长。 本期精选了 12 篇精选文章,12 个开源项目,以及 3 个音视频资源,总字数约 2100 字。 以下是本期内容概览: **[🦄 文…

    未分类 2024 年 12 月 24 日
    23400
  • (2025自测有效!)全网最好的python配置教程【非常非常适合小白】

    前几天我的电脑刚刚重装,把python重新配置了一下。 1.Python环境部署Python3 可应用于多平台包括 Windows、Linux 和 Mac OS X。 Python官网:https://www.python.org/ 进入官网在导航栏选择Dowmloads,选择所使用的系统(以Windows为例) 进入Windows下载页之后选择需要下载的版…

    2025 年 1 月 10 日
    34500
  • JavaScript 延迟加载的方法( 7种 )

    JavaScript脚本的延迟加载(也称为懒加载)是指在网页的主要内容已经加载并显示给用户之后,再加载或执行额外的JavaScript代码。这样做可以加快页面的初始加载速度,改善用户体验,并减少服务器的压力。 以下是几种常见的延迟加载JavaScript的方法: defer 属性: 使用 async 属性: async 属性告诉浏览器立即开始下载脚本,并且在…

    2025 年 1 月 19 日
    36800
  • 2024 GoLand最新激活码,GoLand永久免费激活码2024-12-29 更新

    GoLand 2024最新激活码 以下是最新的GoLand激活码,更新时间:2024-12-29 🔑 激活码使用说明 1️⃣ 复制下方激活码 2️⃣ 打开 GoLand 软件 3️⃣ 在菜单栏中选择 Help -> Register 4️⃣ 选择 Activation Code 5️⃣ 粘贴激活码,点击 Activate ⚠️ 必看!必看! 🔥 获取最新激活…

    2024 年 12 月 29 日
    39300

发表回复

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

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信