说一下乐观锁和悲观锁?

说一下乐观锁和悲观锁?
最新回答
鱼沉秋水

2026-01-29 19:02:54

乐观锁和悲观锁是并发控制中两种截然不同的策略,核心区别在于对数据冲突的假设及处理方式。具体如下:

乐观锁
  • 核心假设:假设冲突很少发生,仅在提交更新时检查是否冲突。
  • 实现方式:不依赖数据库锁,而是通过在数据中增加版本号、时间戳或特定业务字段(如库存数量)作为版本控制依据。更新时检查版本号是否一致,若不一致则判定为冲突。

    版本号:每次更新操作将版本号加一,更新时需匹配当前版本号。

    时间戳:需解决时钟同步问题,确保时间戳的准确性。

    业务字段:如库存数量,仅当字段未变化时允许更新。

  • 适用场景:

    读多写少:冲突检测在提交时进行,避免频繁加锁解锁,提升并发性能。例如社交网络中用户查看帖子远多于编辑帖子。

    冲突概率低:若冲突频繁发生,乐观锁会因重试降低性能。

  • 局限性:

    无法解决脏读问题:仅在提交时检查冲突,无法阻止读取未提交的数据。

    冲突高发时性能下降:频繁失败重试会抵消并发优势。

悲观锁
  • 核心假设:假设最坏情况,每次操作都认为会发生冲突。
  • 实现方式:依赖数据库锁机制,确保事务过程中数据被独占使用。

    数据库实现:通过SELECT ... FOR UPDATE语句对数据行加排他锁,阻止其他事务修改。

  • 适用场景:

    写操作频繁:如金融系统账户交易,需保证数据准确性,防止并发修改导致错误。

    冲突可能性高:通过加锁确保数据一致性。

  • 局限性:

    性能问题:频繁加锁解锁降低并发能力。

    死锁风险:锁持有时间过长可能导致死锁。

    资源占用:长时间占用锁会浪费系统资源。

选择策略
  • 根据业务场景权衡:

    乐观锁适用场景:读操作远多于写操作,且冲突概率低(如社交网络帖子浏览)。可提高并发性能,减少数据库压力。

    悲观锁适用场景:写操作频繁,且冲突概率高(如金融交易)。可保证数据一致性,避免错误。

  • 混合使用:部分场景可结合两种锁。例如更新库存时,先尝试乐观锁更新,失败后转用悲观锁重试。
  • 核心原则:无绝对优劣,需结合业务特点、数据特性及性能要求选择最合适的机制。