Mysql 事务和锁的一些概念和理解

事务的并发性和隔离性由存储引擎(如 InnoDB)和事务隔离级别共同决定。

MySQL(尤其是 InnoDB 引擎)使用 行级锁(row-level locking)来实现事务的隔离性

  • 如果事务 A 修改了某一行,它会对该行加排他锁(X 锁)。
  • 此时事务 B 若也尝试修改或读取(取决于隔离级别)同一行,就可能被阻塞,直到事务 A 提交或回滚。

MySQL 默认隔离级别是 REPEATABLE READ(可重复读),不同级别对并发的影响不同:

  • READ UNCOMMITTED:几乎无阻塞(但可能读到脏数据)。
  • READ COMMITTED:读操作一般不加锁(使用快照读),写操作加行锁。
  • REPEATABLE READ:InnoDB 使用 MVCC + Next-Key Lock 防止幻读,可能在范围查询时加间隙锁(Gap Lock),增加锁竞争。
  • SERIALIZABLE:所有读操作都加共享锁,显著增加阻塞可能性,但依然不是"全局"锁。

两个概念

脏读

脏读 是指一个事务读取了另一个尚未提交的事务所修改的数据。
如果那个未提交的事务后来**回滚(ROLLBACK)**了,那么当前事务读到的数据就是"不存在"的、无效的------这就是所谓的"脏数据"。

例子:

  • MySQL 的 InnoDB 引擎在默认隔离级别(REPEATABLE READ)下禁止脏读

说明一下:

复制代码
-- 事务A
UPDATE accounts SET balance = balance - 100 WHERE user = 'Alice';  -- 余额从500变成400
-- (但还没 COMMIT)

Mysql执行逻辑:

执行这个sql后,数据在物理/内存层面已经被修改了。

InnoDB 会在内存中(Buffer Pool)修改该行的数据页 ,将 balance 从 500 改为 400

  • 同时,它会:
    • Undo Log 中保留旧值(500),用于回滚或 MVCC 快照读。
    • Redo Log 中记录这次修改,用于崩溃恢复。
    • 对该行加上 排他锁(X 锁),防止其他事务同时修改。

在正常隔离级别下,其他事务是看不到这个Update后的400的

原理:

其他事务使用 READ COMMITTED / REPEATABLE READ(默认)
  • InnoDB 使用 MVCC(多版本并发控制)
  • 其他事务执行 SELECT balance FROM accounts WHERE user = 'Alice'; 时:
    • 会通过 Read View 判断当前事务 A 是否已提交。
    • 因为事务 A 未提交 ,所以其他事务看不到 400 ,而是通过 Undo Log 读到旧值 500
  • 只有当事务 A COMMIT 后,这个 400 才对其他事务可见。
    (通俗的讲就是会检查事务A是否全部提交完了,隔离性和原子性的体现)

幻读

幻读 是指在一个事务中,两次执行相同的查询 ,但第二次查询返回了第一次没有的结果(即"凭空出现"的新行),就像出现了"幻影"。
幻读通常发生在插入(INSERT)操作上,而不是更新。

复制代码
-- 事务A 开始
START TRANSACTION;

-- 第一次查询
SELECT * FROM students WHERE score > 80;  -- 返回 0 行

-- 此时,事务B 插入了一条新记录:
INSERT INTO students (id, name, score) VALUES (3, 'Tom', 90);
COMMIT;

-- 事务A 再次执行相同查询
SELECT * FROM students WHERE score > 80;  -- 现在返回 Tom!
  • MySQL InnoDB 在 REPEATABLE READ 级别下通过"Next-Key Lock"(行锁 + 间隙锁)也防止了幻读(这是 InnoDB 的特殊优化,不同于 SQL 标准)。
  • 幻读新增行 导致查询结果集变大(针对新插入的行)---结果集会变大。

区别:

总结就是 放心使用。。遇到其他问题再说

MySQL 默认(InnoDB + REPEATABLE READ)

  • 不会出现 脏读
  • 不会出现 不可重复读
  • 也不会出现幻读(得益于间隙锁)
相关推荐
惜分飞3 分钟前
ORA-600 kcratr_nab_less_than_odr和ORA-600 4193故障处理--惜分飞
数据库·oracle
chian-ocean3 分钟前
CANN 生态进阶:利用 `profiling-tools` 优化模型性能
数据库·mysql
m0_550024636 分钟前
持续集成/持续部署(CI/CD) for Python
jvm·数据库·python
AC赳赳老秦7 分钟前
代码生成超越 GPT-4:DeepSeek-V4 编程任务实战与 2026 开发者效率提升指南
数据库·数据仓库·人工智能·科技·rabbitmq·memcache·deepseek
啦啦啦_999921 分钟前
Redis-2-queryFormat()方法
数据库·redis·缓存
玄同7651 小时前
SQLite + LLM:大模型应用落地的轻量级数据存储方案
jvm·数据库·人工智能·python·语言模型·sqlite·知识图谱
吾日三省吾码1 小时前
别只会“加索引”了!这 3 个 PostgreSQL 反常识优化,能把性能和成本一起打下来
数据库·postgresql
chian-ocean1 小时前
百万级图文检索实战:`ops-transformer` + 向量数据库构建语义搜索引擎
数据库·搜索引擎·transformer
那个村的李富贵2 小时前
解锁CANN仓库核心能力:50行代码搭建国产化AIGC图片风格迁移神器
mysql·信息可视化·aigc·cann
小Tomkk2 小时前
数据库 变更和版本控制管理工具 --Bytebase 安装部署(linux 安装篇)
linux·运维·数据库·ci/cd·bytebase