https://javaguide.cn/distributed-system/distributed-lock.html 内容冗余,没有重点,讲解混乱。
#2919 · closed · 1 comments
View on GitHub ↗
[为什么需要分布式锁
在多线程环境中,如果多个线程同时访问并修改同一份共享资源(例如商品库存、外卖订单),且没有互斥、原子更新、乐观锁或唯一约束等保护,就可能出现数据不一致、重复处理、超卖等问题,影响程序的正确性和稳定性。
举个例子,假设现在有 100 个用户参与某个限时秒杀活动,每位用户限购 1 件商品,且商品的数量只有 3 个。如果不对共享资源进行互斥访问,就可能出现以下情况:
线程 1、2、3 等多个线程同时进入抢购方法,每个线程对应一个用户。
线程 1 和线程 2 分别代表两个不同用户,它们几乎同时读到库存还剩 1 件,于是都通过库存校验,继续创建订单、扣减库存。
线程 1 继续执行,将库存数量减少 1 个,然后返回成功。
线程 2 也继续执行,将库存数量减少 1 个,然后返回成功。
最终两个请求都成功,但库存只够卖 1 件,于是发生超卖。
这里的限购校验和库存扣减是两个不同的约束:限购主要解决同一用户重复购买的问题,库存扣减主要解决多个用户竞争同一份库存的问题。
我想知道为什么需要分布式锁,但是我看完了,才发现并没有讲清楚,甚至感觉极其的应付。
<img width="1346" height="968" alt="Image" src="https://github.com/user-attachments/assets/de077d0f-f018-464c-a07a-bd690e625c0b" />
这张图能讲清楚什么问题,只能让初学者以为不同JVM进程访问同一临界资源。实际上并非如此。
Comments
> [为什么需要分布式锁
>
> 在多线程环境中,如果多个线程同时访问并修改同一份共享资源(例如商品库存、外卖订单),且没有互斥、原子更新、乐观锁或唯一约束等保护,就可能出现数据不一致、重复处理、超卖等问题,影响程序的正确性和稳定性。
>
> 举个例子,假设现在有 100 个用户参与某个限时秒杀活动,每位用户限购 1 件商品,且商品的数量只有 3 个。如果不对共享资源进行互斥访问,就可能出现以下情况:
>
> 线程 1、2、3 等多个线程同时进入抢购方法,每个线程对应一个用户。 线程 1 和线程 2 分别代表两个不同用户,它们几乎同时读到库存还剩 1 件,于是都通过库存校验,继续创建订单、扣减库存。 线程 1 继续执行,将库存数量减少 1 个,然后返回成功。 线程 2 也继续执行,将库存数量减少 1 个,然后返回成功。 最终两个请求都成功,但库存只够卖 1 件,于是发生超卖。 这里的限购校验和库存扣减是两个不同的约束:限购主要解决同一用户重复购买的问题,库存扣减主要解决多个用户竞争同一份库存的问题。
>
> 我想知道为什么需要分布式锁,但是我看完了,才发现并没有讲清楚,甚至感觉极其的应付。
>
> <img alt="Image" width="1346" height="968" src="https://private-user-images.githubusercontent.com/211474977/655288083-de077d0f-f018-464c-a07a-bd690e625c0b.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODk4ODM2NjgsIm5iZiI6MTc4OTg4MzM2OCwicGF0aCI6Ii8yMTE0NzQ5NzcvNjU1Mjg4MDgzLWRlMDc3ZDBmLWYwMTgtNDY0Yy1hMDdhLWJkNjkwZTYyNWMwYi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwOTIwJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDkyMFQwNTQ5MjhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0wZTFjMWM4YTc3MzQ2NDFmOGE3YTgzZDQ5NmEwOWQ4NzU2YjU4MWE0MmYzYTE0ZmVjYTE1Yzg5ZDMwZDY0MjNmJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.FMyPvNnULQmbGx-C0n9moZZRy1qHVXPUOi1pnPGUW2M">
> 这张图能讲清楚什么问题,只能让初学者以为不同JVM进程访问同一临界资源。实际上并非如此。
感谢反馈,这一节确实没把重点讲清楚。我已经调整了讲解顺序和配图,重点说明本地锁为什么无法协调多个 JVM,以及什么时候需要分布式锁,后续更新上线。
另外补充一点:不同 JVM 不共享堆内存,但可以访问同一条数据库记录。原文里的“共享资源”指的是这类外部数据,这里之前表达得不够清楚。