游乐游手机版
首页/AI教程/文章详情

软件开发进阶技能:数据库进阶(三)

时间:2026-06-07 16:10
事务与并发控制通过ACID特性、四种隔离级别及MVCC机制保障数据一致性。InnoDB默认可重复读级别借助Next-KeyLock防幻读。MVCC实现无锁高并发读。行锁、间隙锁等结合自动死锁检测,合理缩短事务可提升性能。

第三部分:事务与并发控制 —— 数据一致性的守护者

多个用户同时读写数据库,数据一致性怎么保证?这就得靠事务和锁机制了。

3.1 事务的 ACID 特性回顾
原子性(Atomicity):事务里的所有操作,要么全做,要么全撤销,没有中间状态。

一致性(Consistency):事务跑完以后,数据库要从一个一致状态跳到另一个一致状态,完整性约束不能破坏。

隔离性(Isolation):并发执行的事务之间,不能互相干扰。

持久性(Durability):一旦事务提交,结果就永久存下来了,就算系统崩溃也丢不了。

数据库靠日志(Redo Log 管持久性,Undo Log 管原子性和回滚)和锁 MVCC(管隔离性)来实现 ACID。

3.2 隔离级别与现象
SQL 标准定了四种隔离级别,从低到高:
image.png
三种并发问题,得搞清楚:

脏读:一个事务读到了另一个还没提交的事务改的数据。要是后者回滚了,读到的就是废数据。

不可重复读:同一事务里,两次读同一个行,结果不一样——因为另一个事务改了这行并提交了。

幻读:同一事务里,两次查询返回的记录条数不一样——因为另一个事务插了或删了符合条件的数据。

MySQL InnoDB 默认隔离级别是 REPEATABLE READ,它靠 MVCC 和 Next-Key Lock(间隙锁加行锁)解决了幻读,实际效果接近 SERIALIZABLE,但性能好得多。

3.3 MVCC —— 无锁的高并发读
MVCC 是 InnoDB 和 PostgreSQL 这类数据库实现高并发的核心招数。思路很简单:写操作不堵读操作,读操作只读数据的一个快照。

3.3.1 InnoDB 中的 MVCC 实现
InnoDB 给每行数据加了两个隐藏字段:

DB_TRX_ID:最后改这行的事务 ID。

DB_ROLL_PTR:指向 Undo Log 里这行的旧版本链。

事务开始时,拿一个全局递增的事务 ID。执行 SELECT 时,只能看到:

修改这行的事务 ID 小于当前事务 ID(已提交的),而且没有活跃事务在改。

或者修改这行的事务 ID 在当前事务的 Read View 里被标记为已提交。

Read View 是个数据结构,记着当前系统里所有活跃(未提交)事务的 ID 列表。事务开始时生成 Read View(RR 级别下只在第一个 SELECT 时生成,整个事务复用;RC 级别下每次 SELECT 都重新生成)。

3.3.2 示例说明 MVCC 如何避免不可重复读
假设有行数据初始是 (id=1, balance=100),trx_id=10。

事务 A(trx_id=20)开始,执行 SELECT balance FROM account WHERE id=1,此时生成 Read View,看到活跃事务没有,所以读到 balance=100。

事务 B(trx_id=21)开始,把 balance 更新成 200,旧版本(100)写进 Undo Log,新行 trx_id=21。

事务 A 再执行 SELECT balance,Read View 还是在事务开始时生成的,事务 21 是活跃事务,大于 Read View 的低水平,所以 A 还是看到旧版本(通过 Undo 链找到版本 trx_id=10),实现了可重复读。

3.4 锁机制:行锁、间隙锁、Next-Key Lock、表锁
InnoDB 支持多粒度锁,最重要的就是行锁和间隙锁。

3.4.1 行锁(Record Lock)
行锁只锁住索引记录。注意:如果查询没走索引,InnoDB 会退化成表锁(实际是把所有行都锁住,效率极差)。

3.4.2 间隙锁(Gap Lock)
间隙锁锁住一个范围(两条索引记录之间的间隙),但不包括记录本身。主要用来防幻读。比如 SELECT * FROM user WHERE id BETWEEN 10 AND 20 FOR UPDATE,会把 id 在 (10,20) 之间的间隙锁住,不让其他事务插入 id=15 的新记录。

3.4.3 Next-Key Lock = 行锁加间隙锁
InnoDB 在 REPEATABLE READ 级别下执行范围查询时,会用 Next-Key Lock,把记录本身和记录前的间隙都锁了,彻底防住幻读。

3.4.4 意向锁(Intention Lock)
这是表级别的锁,表明事务正要或正在持有行锁。目的是在加表锁时快速判断有没有行锁,不用逐行检查。

3.5 死锁的检测与处理
死锁就是两个或多个事务互相握着对方需要的锁,导致无限等下去。InnoDB 会自动检测死锁(靠等待图),然后挑一个事务回滚(一般是更新行数少的那个),让另一个继续执行。应用程序得处理好重试逻辑。

死锁例子与避免

-- 事务1BEGIN;UPDATE account SET balance=balance-100 WHERE id=1;UPDATE account SET balance=balance 100 WHERE id=2;COMMIT;-- 事务2BEGIN;UPDATE account SET balance=balance-50 WHERE id=2;UPDATE account SET balance=balance 50 WHERE id=1;COMMIT;

要是两个事务几乎同时跑,事务1锁住了 id=1,事务2锁住了 id=2,接着各自想锁另一个 id,死锁就发生了。

怎么避免?

所有事务按相同顺序访问资源(比如总是先更新 id=1 再 id=2)。

尽量用低隔离级别(比如 RC,没有间隙锁,死锁概率更低)。

控制事务大小,快点提交。

用 SELECT ... FOR UPDATE 提前锁住需要的行。

3.6 应用层事务最佳实践
尽量缩短事务:别在事务里做用户输入、远程调用这种耗时操作,那样会长时间持锁,增加死锁风险,还拖慢并发。

避免在事务里做大 SELECT:如果只是读数据,不要求强一致性,可以在事务外执行。

合理设超时:innodb_lock_wait_timeout 控制行锁等待时间,别让个别事务堵了整个系统。

来源:https://developer.aliyun.com/article/1739359
上一篇软件开发进阶:编程语言深度运用(六) 下一篇阿里云OpenCode:国产开源AI编程Agent替代Claude Code全攻略
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
幻灯片排版优化AI智能助手,节省时间与精力
AI教程 · 2026-07-01

幻灯片排版优化AI智能助手,节省时间与精力

说起来,今天想和大家聊聊一个特别实在的话题:怎么用AI工具把PPT排版效率提上去,真正省下时间和精力。谁不想在忙忙碌碌的工作里找到点儿省事的诀窍呢?我有个朋友,为了准备一次重要汇报,连着熬了三个晚上折腾PPT,最后出来的效果也就是勉强及格。要是当时他能用上AI工具,结果会不会完全不一样?PPT排版优

AI排版软件让文档制作轻松又高效
AI教程 · 2026-07-01

AI排版软件让文档制作轻松又高效

AI智能排版工具通过自动识别文档结构、调整格式,显著提升排版效率。实际案例显示,文档处理时间可缩短约50%,项目交付效率提高40%。其功能涵盖自动排版、模板库、智能校对等,重构了文档制作流程,使用户专注内容创作,提升专业形象与市场竞争力。

Karpathy晒邮件曝光注意力机制真正起源:10年前三项独立研究
AI教程 · 2026-07-01

Karpathy晒邮件曝光注意力机制真正起源:10年前三项独立研究

2014年,三项研究几乎同时独立提出注意力机制:DzmitryBahdanau在YoshuaBengio实验室开发出RNNSearch(后称注意力),AlexGraves和JasonWeston团队也发表了类似机制。该思想源于解决循环神经网络信息瓶颈的需求,采用可微加权平均,成为深度学习核心算法。

如何选择AI排版工具与技巧提升内容创作效率
AI教程 · 2026-07-01

如何选择AI排版工具与技巧提升内容创作效率

AI排版工具推荐与技巧:如何提升内容创作效率与视觉设计效果其实,AI排版早已成为内容创作领域的热门话题。在信息爆炸的时代,大家都想知道如何让内容在海量信息中脱颖而出。简单来说,AI排版就是借助人工智能技术自动化处理文本、图像等内容的布局与设计。不妨想象一下:星巴克菜单上那些赏心悦目的排版,背后可能就

AI公文写作助手助力文档创作,高效节省时间精力
AI教程 · 2026-07-01

AI公文写作助手助力文档创作,高效节省时间精力

AI公文写作助手可将企业文档处理效率提升30%以上,北京国企公文撰写时间缩短50%。WPSAI文档处理能一键生成专业文档,深圳创业公司效率提高70%。未来AI将更智能化,自动调整文档风格。