温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

为何数据库要用SERIALIZABLE可串行化

发布时间:2026-11-05 15:22:13 来源:亿速云 阅读:90 作者:小樊 栏目:数据库

在数据库中采用 SERIALIZABLE(可串行化)隔离级别,核心目的是为了保证并发事务执行的结果,与某种“依次串行执行”这些事务的结果完全一致,从而彻底避免各类并发异常。

下面从“为什么需要它”“它解决了什么问题”“代价是什么”三个角度说明。


一、为什么要用 SERIALIZABLE:并发会带来问题

当多个事务同时读写数据时,如果不加控制,会出现经典问题:

  1. 脏读(Dirty Read)
    • 读到别的事务未提交的数据,之后该事务回滚
  2. 不可重复读(Non‑repeatable Read)
    • 同一事务内两次读同一行,结果不同(被别的事务修改并提交)
  3. 幻读(Phantom Read)
    • 同一查询条件,两次查询结果集行数不同(别的事务插入/删除)
  4. 写偏斜(Write Skew)
    • 两个事务基于“各自读到的状态”做更新,结果破坏业务约束
      (如:两人同时请病假,系统允许人数超限)

SERIALIZABLE 能避免上述所有问题。


二、SERIALIZABLE 保证什么

多个并发事务的执行效果
等价于 按某种顺序一个一个串行执行

这意味着:

  • 不会读到“不合理的中间状态”
  • 业务约束(如唯一性、数量限制)永远成立
  • 开发者可以“像单线程一样”思考业务逻辑

三、典型使用场景(为什么“必须”用)

1. 强一致性业务

  • 银行转账
  • 库存扣减
  • 订单与账户余额联动

这些场景不能接受“逻辑上不可能发生”的结果。

2. 存在“读后写”依赖

例如:

SELECT count(*) FROM seats WHERE booked = false;
-- 如果少于 10,则插入
INSERT INTO seats(...) ;

低隔离级别下可能超卖,SERIALIZABLE 可防止。

3. 法律 / 审计要求

  • 结果必须可解释、可复放
  • 不允许“并发导致的不确定状态”

四、SERIALIZABLE 的实现方式(简要)

  • 两阶段锁(2PL):读写都加锁,冲突事务排队
  • 多版本 + 冲突检测(如 SSI,Serializable Snapshot Isolation)
    • PostgreSQL 使用这种方式
    • 读不阻塞写,写冲突时回滚一个事务

五、代价:为什么不是默认都用

SERIALIZABLE 并非“免费”:

  • 并发度下降
  • 锁等待 / 事务回滚增多
  • 吞吐量可能显著降低

所以实践中:

  • 高频简单读写 → READ COMMITTED
  • 关键一致性操作 → SERIALIZABLE(或显式加锁)

一句话总结

数据库用 SERIALIZABLE,是为了在并发环境下,依然保证“结果正确且可解释”,牺牲一定性能,换取最强的一致性保障。

如果你愿意,我也可以对比 SERIALIZABLE vs REPEATABLE READ,或结合某个数据库(MySQL / PostgreSQL)具体说明。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手