zoukankan      html  css  js  c++  java
  • Java++:一文搞懂分布式锁及其业务场景

    为什么用分布式锁?

    在讨论这个问题之前,我们先来看一个业务场景:

    系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单。

    由于系统有一定的并发,所以会预先将商品的库存保存在redis中,用户下单的时候会更新redis的库存。

    此时系统架构如下:

    但是这样一来会产生一个问题:

    假如某个时刻,redis里面的某个商品库存为1,此时两个请求同时到来,其中一个请求执行到上图的第3步,更新数据库的库存为0,但是第4步还没有执行。

    而另外一个请求执行到了第2步,发现库存还是1,就继续执行第3步。

    这样的结果,是导致卖出了2个商品,然而其实库存只有1个。

    很明显不对啊!这就是典型的库存超卖问题 !!!

    此时,我们很容易想到解决方案:

    用锁把2、3、4步锁住,让他们执行完之后,另一个线程才能进来执行第2步。

    按照上面的图,在执行第2步时,使用Java提供的synchronized或者ReentrantLock来锁住,然后在第4步执行完之后才释放锁。

    这样一来,2、3、4 这3个步骤就被“锁”住了,多个线程之间只能串行化执行。

    但是好景不长,整个系统的并发飙升,一台机器扛不住了。

    现在要增加一台机器,如下图:

    增加机器之后,系统变成上图所示,我的天!

    假设此时两个用户的请求同时到来,但是落在了不同的机器上,那么这两个请求是可以同时执行了,还是会出现库存超卖的问题。

    为什么呢?因为上图中的两个A系统,运行在两个不同的JVM里面,他们加的锁只对属于自己JVM里面的线程有效,对于其他JVM的线程是无效的。

    因此,这里的问题是:Java提供的原生锁机制在多机部署场景下失效了。

    这是因为两台机器加的锁不是同一个锁(两个锁在不同的JVM里面)。

    那么,我们只要保证两台机器加的锁是同一个锁,问题不就解决了吗?

    此时,就该分布式锁隆重登场了,分布式锁的思路是:

    在整个系统提供一个全局、唯一的获取锁的“东西”,然后每个系统在需要加锁时,都去问这个“东西”拿到一把锁,这样不同的系统拿到的就可以认为是同一把锁。

    至于这个“东西”,可以是 Redis、Zookeeper,也可以是数据库。

    文字描述不太直观,我们来看下图:

    通过上面的分析,我们知道了库存超卖场景在分布式部署系统的情况下使用Java原生的锁机制无法保证线程安全,所以我们需要用到分布式锁的方案。

    那么,如何实现分布式锁呢?接着往下看!

    待更新....

  • 相关阅读:
    java_doc
    zai~~myGODDDD
    get span time
    someThing about thread
    互斥
    http://www.vchelp.net/services/about_us/itbookreview_intro.asp
    (十三)sealed、new、virtual、abstract 和 override java程序员
    (15) 常用基础知识 java程序员
    (14)abstract class 和 interface java程序员
    (16) 结构和类 java程序员
  • 原文地址:https://www.cnblogs.com/codingmode/p/15331659.html
Copyright © 2011-2022 走看看