没有图形,只通过大量文字进行说明。分布式锁:redis分布式锁, zk分布式锁, 数据库做分布式锁
setnx key value ex 10 原子操作
AB两个线程减库存业务,假设库存是10
A线程获取锁,B线程等待,此时A线程释放锁,程序还未执行完成。此时B线程获取锁,此时A,B都将库存减到9,与业务不符。
解决办法:锁续期。
为了解决单机redis瓶进,采用redis集群。一主一从,线程A从主机获取锁,此时主宕机,线程B从从机也获取了锁
解决办法:使用红锁 5(奇数)台redis集群,没有主从概念,假设编号为B1 B2 B3 B4 B5。请求依次执行,当一半以上加锁成功才算加锁成功,此时A线程依次加锁成功B1 B2 B3即获取锁成功。 线程B 加锁B4 B5成功,没有获取锁。此时还存在一个问题,如果B3宕机,马上重启成功。此时线程B 加锁B3 B4 B5成功,也获取了锁,这是红锁存在的问题。解决办法:延时重启
其实实际中采用单机redis做分布式锁即可,使用分布式框架redisson。
5.线程A获取锁,此时 如果程序jvm线程stw, 会导致锁丢失。仍然想获取锁可以使用 zk(节点)+数据库。线程A获取锁,返回将锁存放在数据库中,此时JVM stw, 线程b去获取锁,修改锁,与数据库已经存在的锁标识进行对比。
锁的id作为主键索引或者唯一索引
-----------程序A---------->程序B----->----------
| |
|
|
DB DB
AB两个串行执行的程序都有数据库操作,程序A执行后,程序B出现异常时,数据库如何进行回滚
采用了协调者角色,框架iso,seateAT
两段式提交
扩展:三段式提交
程序请求后直接返回
自己手写mq监控程序(定时任务+web)请求mq和操作数据库