乐观锁 & 悲观锁

  |   2 评论   |   336 浏览

何谓 “锁”

业务逻辑的实现过程中,往往需要保证数据访问的排他性。此时,我们就需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓的 “ 锁 ” ,即给我们选定的目标数据上锁,使其无法被其他程序修改。

悲观锁

悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

排它锁

  • 排它锁(X锁)又称为写锁,若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。它防止任何其它事务获取资源上的锁,直到在事务的末尾将资源上的原始锁释放为止。

共享锁

  • 共享锁(S锁)又称为读锁,若事务T对数据对象A加上S锁,则事务T只能读A;其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

更新锁

  • 更新锁(U锁)放置在可更新的资源(如行、页、表)上的锁。更新锁用于防止常见形式的死锁,这类死锁在多个会话锁定资源并且稍后可能更新资源时发生。

乐观锁

乐观锁,大多是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

部分实践&应用场景

  • 一份订单对应多份商品/库存 :数据强一致性需求。
  • 微信红包/秒杀 :web2.0快速响应需求。
  • 合适的版本对象 :库存vs版本号?
  • mybatis插件 :将乐观锁的实现机制与业务开发隔离,逻辑对开发人员透明。 —— 博文地址

评论

发表评论