温馨提示×

温馨提示×

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

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

为什么要用SERIALIZABLE可串行化

发布时间:2026-09-04 23:40:59 来源:亿速云 阅读:91 作者:小樊 栏目:数据库

在数据库事务隔离级别中,SERIALIZABLE(可串行化) 是最高的隔离级别。之所以要使用它,核心原因是:在并发环境下,保证数据的一致性(Correctness),避免各种并发异常。

下面从“问题 → 解决 → 代价 → 适用场景”来说明。


一、不用高隔离级别会出什么问题?

如果隔离级别较低(如 READ COMMITTED、REPEATABLE READ),并发事务可能出现:

  1. 脏读(Dirty Read)

    • 读到别的事务未提交的数据,对方回滚后数据无效。
  2. 不可重复读(Non-repeatable Read)

    • 同一事务内两次读同一数据,结果不同(被别的事务修改并提交)。
  3. 幻读(Phantom Read)

    • 同一查询条件,两次查询结果行数不同(别的事务插入/删除了数据)。
  4. 写冲突导致业务错误

    • 例如:
      • 两个事务同时查“库存=1”
      • 都扣库存
      • 最后库存变成 -1(超卖)

这些问题在金融、库存、账务、票务等场景中是不可接受的。


二、SERIALIZABLE 解决了什么?

SERIALIZABLE 保证:

多个事务并发执行的结果,等价于某种“串行执行”的结果。

也就是说:

  • 不会出现脏读、不可重复读、幻读
  • 不会出现逻辑上的并发错误
  • 数据库状态始终“看起来像是一个人一个接一个操作”

它通常通过:

  • 锁(行锁、间隙锁、范围锁)
  • 或多版本 + 冲突检测(如 Serializable Snapshot Isolation)

来实现。


三、为什么“要用”而不是“默认用”?

因为 SERIALIZABLE 有代价:

  • 并发度下降(容易锁等待、死锁)
  • 吞吐量降低
  • 延迟可能增加

所以:

  • 不是所有系统都需要
  • 只在“正确性 > 性能”时使用

四、典型使用场景

适合用 SERIALIZABLE 的场景:

  • 银行转账
  • 账户余额更新
  • 库存扣减
  • 票务/座位分配
  • 计数器、配额控制
  • 任何“读后写”依赖业务逻辑

示例:

BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT balance FROM account WHERE id = 1;
-- 业务判断
UPDATE account SET balance = balance - 100 WHERE id = 1;
COMMIT;

这样能保证不会两个事务同时扣成负数。


五、一句话总结

用 SERIALIZABLE,是因为在并发系统中,有时候“绝对不能算错”比“算得快”更重要。

如果你愿意,我也可以帮你:

  • 对比四种隔离级别
  • 用例子讲“幻读 vs 不可重复读”
  • 讲 SERIALIZABLE 在 MySQL / PostgreSQL 中的实现差异
向AI问一下细节

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

AI
助
手