
文章目录一、四个隔离级别举例说明1. Read Uncommitted:可以看到别人尚未提交的修改2. Read Committed:只能看到已经提交的数据3. Repeatable Read:同一事务重复读取通常保持一致标准定义下仍可能出现幻读4. Serializable:效果如同事务一个接一个执行四个级别对照二、Repeatable Read 和 Read Committed 作为常见默认值有时候“重复看到旧值”为什么反而合理?它不会永远看到旧值大多数单条 SQL 感觉不到这个区别MySQL 为什么选择 Repeatable Read?想读取最新数据怎么办?方法一:结束当前事务方法二:使用 Read Committed方法三:读取并准备修改时加锁Repeatable Read 也不是万无一失最后的理解一、四个隔离级别举例说明可以把四个隔离级别理解为:当两个事务同时操作数据库时,一个事务能看到另一个事务进行到哪一步。隔离能力从弱到强:Read Uncommitted ↓ Read Committed ↓ Repeatable Read ↓ Serializable代价通常是:隔离越强,并发限制越多,也越可能发生等待或事务重试。1. Read Uncommitted:可以看到别人尚未提交的修改初始余额:Alice 余额 = 100事务 A 扣款,但还没有提交:BEGIN;UPDATEaccountsSETbalance=0WHEREname='Alice';-- 尚未 COMMIT事务 B 此时查询:SELECTbalanceFROMaccountsWHEREname='Alice';可能看到:0随后事务 A 发生错误并回滚:ROLLBACK;数据库实际余额重新变成:100事务 B 刚才读取的0是一个从未真正生效的数据,这叫脏读:事务 A:100 ──修改为 0── 最后回滚为 100 ↑ 事务 B: 读到了 0类比:你看到了别人还没提交的草稿,但对方最后把草稿删掉了。2. Read Committed:只能看到已经提交的数据初始商品价格:价格 = 100事务 A 第一次读取:BEGIN;SELECTpriceFROMproductsWHEREid=1;结果:100然后事务 B 修改价格并提交:BEGIN;UPDATEproductsSETprice=120WHEREid=1;COMMIT;事务 A 再次读取同一行:SELECTpriceFROMproductsWHEREid=1;这次结果可能是:120同一个事务里,两次读取同一行,结果不同:事务 A 第一次读:100 事务 B 修改提交:120 事务 A 第二次读:120这叫不可重复读。Read Committed 避免了脏读,因为只有事务 B 提交后,事务 A 才能看到120。但它不保证同一个事务中的多次查询结果一致。类比:你只能看到别人正式发布的内容,但你刷新页面后,内容可能已经变了。3. Repeatable Read:同一事务重复读取通常保持一致还是刚才的价格:价格 = 100事务 A 第一次读取:BEGIN;SELECTpriceFROMproductsWHEREid=1;