Mysql--基础知识点--109--SERIALIZABLE事务隔离级别

MySQL 的 SERIALIZABLE(串行化) 是最高的事务隔离级别。它通过强制事务串行执行来完全避免脏读、不可重复读和幻读,但会显著降低并发性能。

核心机制

在 InnoDB 中,SERIALIZABLE 的实现方式如下:

  • 自动对普通 SELECT 加锁

    所有普通的 SELECT 语句都会被隐式转换为 SELECT ... LOCK IN SHARE MODE(共享锁)。读取的每一行都会加锁,直到事务结束才释放。

  • 当前读(SELECT ... FOR UPDATE/SHAREUPDATEDELETE 的行为与 REPEATABLE READ 下一致,仍然使用行锁 + 间隙锁(Next-Key Lock)。

  • 锁冲突导致等待或超时

    如果一个事务要读取某行,而另一个事务正在修改(持有排他锁),则读取事务必须等待。同样,修改操作也必须等待其他事务释放共享锁。

与 REPEATABLE READ 的关键区别

特性 REPEATABLE READ SERIALIZABLE
普通 SELECT 快照读(无锁,基于 MVCC) 加共享锁(当前读)
并发读-读 无阻塞 无阻塞(共享锁兼容)
并发读-写 读不阻塞写(快照读) 读阻塞写(写事务等待读事务释放共享锁)
并发写-读 写阻塞其他写,但不阻塞快照读 写阻塞读(读事务等待写提交)
幻读处理 当前读用间隙锁避免,快照读无幻读 所有读都是当前读,自然无幻读
性能 较高 较低(大量锁等待)

使用场景与注意事项

  • 何时使用:只有在需要绝对数据一致性且并发极低的场景(如财务对账、某些批量操作)才考虑使用。多数情况下 REPEATABLE READ 已足够安全。

  • 死锁风险增加:由于加锁范围更广,事务之间更容易形成死锁。

  • 如何启用

    sql 复制代码
    SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    -- 或
    SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  • 默认隔离级别:MySQL 默认是 REPEATABLE READ,而不是 SERIALIZABLE。

简单示例说明阻塞

sql 复制代码
-- 事务 A
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
SELECT * FROM user WHERE id = 1;  -- 对 id=1 的行加共享锁

-- 事务 B(此时执行会阻塞,直到事务 A 提交或回滚)
BEGIN;
UPDATE user SET name='new' WHERE id = 1;  -- 需要排他锁,被 A 的共享锁阻塞

总结:SERIALIZABLE 通过让所有读操作都加锁来获得最高隔离性,但会严重限制并发,通常只在对数据一致性要求极高且写入很少的场景下使用。对于绝大多数应用,使用 InnoDB 默认的 REPEATABLE READ 即可获得足够的一致性保障。

相关推荐
01_ice17 小时前
MySQL事务
数据库·mysql
名字还没想好☜17 小时前
Go 的 database/sql 连接池实战:SetMaxOpenConns 怎么配、连接泄漏怎么查
数据库·sql·golang·go·数据库连接池
大眼、不聚光17 小时前
2.oracle--表空间管理
数据库·oracle
字节跳动数据库17 小时前
火山 PostgreSQL Serverless × 飞书妙搭:把 AI 装进数据库,一句话唤醒数据智能
数据库·人工智能·后端
玛丽莲茼蒿17 小时前
Redis(六)—— Redis高级
数据库·redis·缓存
Wang's Blog18 小时前
PostgreSQL笔记22: WAL日志与崩溃恢复原理
数据库·笔记·postgresql
陈聪.19 小时前
企业级 NoSQL 数据库 Redis 核心知识整理
数据库·redis·nosql
翼龙云_cloud19 小时前
腾讯云国际代理商:CDB数据库自动备份和异地灾备配置 从快照到跨区域恢复
运维·数据库·云计算·腾讯云
小屁孩你滑稽掉了19 小时前
prisma操作数据库的方法使用教程(简洁版)
数据库·node.js·prisma·fastify
l1t19 小时前
利用DuckDB luajit插件和openblas库对表中数据做矩阵运算
数据库·线性代数·矩阵·duckdb