跳到正文
Elaine Blog
返回

ACID 与隔离级别

MyBatis、MySQL 与数据架构

事务不是给 SQL 加一个注解,而是把必须共同成功的一组状态变化划进边界。隔离级别控制并发事务互相可见的程度;级别越高不等于业务一定越正确。

Table of contents

Open Table of contents

用转账理解 ACID

ACID 不是四个独立开关。Undo、Redo、锁、MVCC、刷盘策略和应用事务边界共同实现这些性质。

四种隔离级别

级别典型可见性
READ UNCOMMITTED可能读到未提交数据
READ COMMITTED每条语句看到开始时已提交的快照
REPEATABLE READ同一事务的普通一致性读通常复用快照
SERIALIZABLE约束最强,并发与等待成本也通常更高

MySQL InnoDB 默认是 REPEATABLE READ。MySQL 的具体行为不能只按教科书现象表推断:普通快照读、SELECT ... FOR UPDATE 锁定读、更新语句采用的机制不同。

业务正确性仍要显式设计

两个请求都先读库存 1,再各自减 1,单靠“可重复读”不必然避免丢失更新。可以用条件更新:

UPDATE inventory
SET available = available - 1
WHERE sku_id = ? AND available > 0;

然后检查影响行数。也可使用 FOR UPDATE 悲观锁或版本号乐观锁。实验室的 updateStatus 展示了版本号方案。

事务要短:不要在持锁事务中调用远程服务、等待人工输入或处理大文件。失败时回滚整个业务操作,并让重试具备幂等性。

参考 InnoDB 隔离级别

下一步

继续阅读06-10 InnoDB 锁、死锁与锁等待,观察事务竞争时数据库究竟锁住了什么。


分享这篇文章:

上一篇
排序、分页、Join 与子查询优化
下一篇
InnoDB 锁、死锁与锁等待