在部分情况下,要保证操作在整个集群内是同步的,以操作库存为例,多个减操作需要同步,常见的有两种方式:
1. 采用类CAS的方式,先查询库存,然后使用update xxx set num=num-1 where num=:num;这样可保证库在本次修改之前未被修改;
2. 使用分布式锁,保证同时只有一个地方在修改库存。
这里向大家展示一个基于redis的分布式锁。主要涉及三个类:
1. DistributedLockUtil对外提供获取分布式锁的方法;
2. DistributedLock 分布式锁接口,定义分布式锁支持的方法,主要有acquire和release;
3. JedisLock实现DistributedLock接口,是基于redis的分布锁实现 ;
需要使用StringRedisTemplate,如对spring boot整合redis不熟悉,请参考spring boot项目实战:redis.
DistributedLock接口
public interface DistributedLock {
/**
* 获取锁
* @author yangwenkui
* @time 2016年5月6日 上午11:02:54
* @return
* @throws InterruptedException
*/
public boolean acquire();
/**
* 释放锁
* @author yangwenkui
* @time 2016年5月6日 上午11:02:59
*/
public void release();
}
JedisLock基于redis的分布式锁实现
public class JedisLock implements DistributedLock{
private static Logger logger = LoggerFactory.getLogger(JedisLock.class);
private static StringRedisTemplate redisTemplate;
/**
* 分布式锁的键值
*/
String lockKey; //锁的键值
int expireMsecs = 10 * 1000; //锁超时,防止线程在入锁以后,无限的执行等待
int timeoutMsecs = 10 * 1000; //锁等待,防止线程饥饿
boolean locked = false; //是否已经获取锁
/**
* 获取指定键值的锁
*