优惠券秒杀 - - 乐观锁悲观锁

—————————————————————————————
问题一: 200线程,但只有100券,出现超卖现象

悲观锁(读少写多直接锁) 和 乐观锁(读多写少判断先)
乐观锁
法一: add version
法二: cas法 (Compare-And-Swap)
1.判断是否等于查时的stock
发现当所有人并行查询100时,只有第一个成功,
其他都无法取得,导致200个请求买100张,只抢到20张
2.判断是否还有余票
总结
—————————————————————————–
对于大额优惠券,一人一单
大概思路:
1.直接锁用户的id.toString—>锁的是新new的String对象,不得行
2.锁id.toString.intern()—>根据常量池找相同内容的对象,锁的是同一个string
3.锁的范围应该是整个添加业务
4.锁的操作对象如果是this,那么事务会失效,
因为事务生效的前提: 调用者是spring的代理对象
——————————————————————————-
集群模式下, 同一个用户两次购买优惠券还是能够成功,无法做到一人一张.
究其根本, 一个SpringbootApplication有一个jvm虚拟机,且有唯一配套的锁监视器.
这种情况下跑多个线程是可以实现一人一张
但是如果有多个SpringbootApplication启动,就对应着多个jvm及其配套的锁监视器
如果同一用户走多个服务器发出请求,那么可能就会出现能买好多张的情况

在单机环境下,通过 synchronized 或 JVM 内的锁机制可以保证同一用户在并发请求下“一人一单”。
但是在集群环境下,每个应用实例运行在独立 JVM 中,各自维护独立的锁对象,锁之间互不通信,
因此无法通过 JVM 内的锁来保证全局唯一性。
也就是说,如果同一用户在不同实例(SpringApplication)上同时发起秒杀请求,
可能会成功创建多条订单,违反“一人一张”限制。