PostgreSQL vs MySQL

事务隔离级别本质差异(从“读”到“写”的一次性搞懂)
----------------------------------------------------------------------------------------------


一、为什么「只看 SELECT」一定会把你带沟里?
很多人(包括你刚才)卡在一句话上:

PG RC:每次 SELECT 都重新拍照
那不是和 MySQL RC 一样吗?

这句话在“读”层面是对的,但事务隔离的核心不在读,而在写。

 👉 真正决定数据正确性的,是 UPDATE / DELETE 的语义。

----------------------------------------------------------------------------------------------------------------------------

二、必须先建立的一个统一认知


所有主流数据库都遵循一个铁律:

UPDATE 一定是改“当前数据库中的某一行版本

区别只在于:

  • 你能不能更新一个「你没真正见过的版本」

----------------------------------------------------------------------------------------------------------------------------

三、MySQL InnoDB 的核心模型(RR)

关键词

  •  一致性视图(Read View)
  •  当前读(Current Read)
  •  锁兜底

---------------------------------------------------------------------------------------------------------

1️⃣ MySQL RR 是怎么读的?

START TRANSACTION;
SELECT balance FROM account WHERE id = 1;
  •  生成一个 Read View
  •  事务期间:
    • 普通 SELECT 永远读 同一个快照
  • ✅ 解决不可重复读

---------------------------------------------------------------------------------------------------------

2️⃣ MySQL RR 是怎么写的?(重点)

UPDATE account SET balance = balance - 50 WHERE id = 1;


⚠️ 这里会自动发生一件事:

  •  mysql 无视你的 Read View
  •  强制读取 当前最新版本
  •  然后基于最新版本计算并更新

📌 结论(非常重要)

 MySQL RR:写 ≠ 你看到的那一版

---------------------------------------------------------------------------------------------------------------------------------

3️⃣ 这意味着什么?

```sql

你看到:balance = 100
真实当前:balance = 70
你更新后:balance = 20(成功)

```

  • 数据库不会告诉你:
    • 你刚才的判断基础已经过期了
  • 所以 
    • 逻辑一致性靠你自己兜
    • version 字段 / for update / 业务校验

---------------------------------------------------------------------------------------------------------------------------------

4️⃣ MySQL RR 到底解决了什么?

✅ 解决:

  •  不可重复读
  • 大部分幻读(Next-Key Lock)

❌ 没解决:

  • 基于旧读进行写导致的业务错误

---------------------------------------------------------------------------------------------------------------------------------

四、PostgreSQL RC(为什么像 MySQL RR)

关键词

  • MVCC

  • Statement Snapshot

---------------------------------------------------------------------------------------------------------------------------------

1️⃣ PG RC 是怎么读的?

UPDATE account SET balance = balance - 50 WHERE id = 1;
  • UPDATE 会:

    • 找当前可见的最新版本

    • 基于它更新

📌 效果上:

PG RC ≈ MySQL RR

---------------------------------------------------------------------------------------------------------------------------------

3️⃣ 但注意

PG RC 仍然是:

  • 读:不稳定

  • 写:不校验你“是否基于旧认知”

👉 只是“碰巧行为像”,不是理念一样

---------------------------------------------------------------------------------------------------------------------------------

五、PostgreSQL RR(真正的分水岭)

关键词

  • Transaction Snapshot

  • MVCC 版本校验

  • 写一致性

---------------------------------------------------------------------------------------------------------------------------------

1️⃣ PG RR 是怎么读的?

START TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT balance FROM account WHERE id = 1;

PG 会做一件 MySQL 永远不会做的事

校验:你要更新的这一行,还是不是你当初看到的版本?

3️⃣ 如果版本变了,会发生什么?

你看到:version = v1(balance=100)
当前真实:version = v2(balance=70)

结果:

  • ❌ UPDATE 不会悄悄成功

  • ❌ 不会帮你“自动算最新值”

  • ✅ 更新 0 行 或 serialization failure

📌 PG RR 的核心语义:

你只能修改你真正“见过”的世界

---------------------------------------------------------------------------------------------------------------------------------

六、你问的那句关键理解,正式定稿

❓「PG RR 更新不需要加 version 判断了?」

结论:可以这样理解

但完整表述是:

PG RR 在数据库层,已经帮你做了版本一致性校验

等价于你在 MySQL 里手写的:

UPDATE account
SET balance = balance - 50
WHERE id = 1 AND version = ?

七、Serializable 是在干嘛?

一句话:

Serializable = 把“可能并发错误的执行”,直接拒绝掉

  • 不让你写错

  • 不帮你修错

  • 让你重试

👉 PG 的 Serializable = 最强写正确性保障

---------------------------------------------------------------------------------------------------------------------------------

八、一句话对照表(终极记忆版)

数据库隔离级别本质
MySQLRR读你看到的,写最新的
PGRC读最新的,写最新的
PGRR只能写你见过的
PGSerializable并发不对就重来

九、什么时候差异会真的“坑你”?

👉 所有「先读 → 再算 → 再写」的业务

比如:

  • 扣余额

  • 发放额度

  • 库存扣减

  • 状态流转(NEW → PAYED → DONE)

MySQL RR:

  • 你不加锁 / version,就可能“逻辑上错但数据库不报错”

PG RR:

  • 数据库会直接告诉你:

    “兄弟,你这次判断已经过期了”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值