如果你的系统是分布式集群部署的,那么传统的synchorinzed或者jdk1.5提供的Lock都是依赖本地的jvm虚拟机提供锁服务,分布式服务中多jvm是无法同享锁信息的,故无法提供锁。
分布式场景中数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance),最多只能同时满足两项。所以很多系统在设计之初就要对这三者作出取舍。在互联网领域的绝大多数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证"最终一致性",只要对最终时间是在用户可以接受的范围内即可。
使用redis实现分布式锁
SETNX
SETNX key val 当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。
expire
expire key timeout 为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
delete
delete key 删除key
实现思路:
1:获取锁的时候使用setnx命令设置唯一的key和expire设置锁过期时间。
2: 业务处理完毕之后使用delete命令删除key。
3: 如果业务处理中发生意外无法自动回收key资源,redis将通过expire命令之前设置锁过期时间自动回收。

使用AOP动态配置
Spring的AOP能为我们提供动态的锁获取和锁释放,能大大降低工作量和代码的耦合性。
1:定义切面
基于AOP实现redis分布式锁

ps:方法使用cacheLock注解则能为该方法提供切面服务
2:定义注解
2.1:方法注解
基于AOP实现redis分布式锁
lockedPrefix:key前缀
timeout:轮询锁时间
expireTime:锁过期时间
2.2:参数注解
参数注解定义需要锁的key,LockedObject:定义一个锁key、LockCopmlexObject:定一个复合对象的fiel作为锁的key
基于AOP实现redis分布式锁

基于AOP实现redis分布式锁
3:锁实现代码
3.1获取锁
基于AOP实现redis分布式锁
3.2 释放锁
基于AOP实现redis分布式锁
4 锁使用
基于AOP实现redis分布式锁
流程说明:
1:定义分布式锁切面,当方法使用指定注解,aop注入代码逻辑
2:获取该方法中参数列表定义的锁key
3:判断该key是否被使用中,如果是则轮询,如果超过时间则抛出异常,如果成功获取锁则执行自己方法代码


相关文章: