工具类代码
package com.example.demo.util;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
/**
* @author zhuenbang
* @description
* @date 2018/8/11 10:27
*/
public class RedisLock {
final Logger logger = Logger.getLogger(getClass());
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* @Description: 加锁
* @Param: value = 当前时间+超时时间
* @returns: boolean
* @Author: zhuenbang
* @Date: 2018/8/11 10:49
*/
public boolean lock(String key, String value) {
if (stringRedisTemplate.opsForValue().setIfAbsent(key, value)) {
return true;
}
String currentValue = stringRedisTemplate.opsForValue().get(key);
//如果锁过期
if (!StringUtils.isEmpty(currentValue)
&& Long.parseLong(currentValue) < System.currentTimeMillis()) {
//获取上一个锁的时间
String oldValue = stringRedisTemplate.opsForValue().getAndSet(key, value);
if (!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)) {//防止程序错误造成的死锁
return true;
}
}
return false;
}
/**
* @Description: 解锁
* @Param: [key, value]
* @returns: void
* @Author: zhuenbang
* @Date: 2018/8/11 11:00
*/
public void unlock(String key, String value) {
try {
String currentValue = stringRedisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
stringRedisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Exception e) {
logger.errorv("【redis分布式锁】解锁异常{}", e.getMessage());
}
}
}
业务类使用
package com.example.demo.order;
import com.example.demo.util.RedisLock;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author zhuenbang
* @description
* @date 2018/8/11 11:03
*/
@Service
public class OrderService {
final Logger logger = Logger.getLogger(getClass());
public static final int TIMEOUT = 5 * 1000;//设置超时时间为5秒
@Autowired
private RedisLock redisLock;
/**
* @Description: 模仿使用redis分布式锁
* @Param: []
* @returns: void
* @Author: zhuenbang
* @Date: 2018/8/11 11:06
*/
private void deductionStock() {
//加锁
long time = System.currentTimeMillis() + TIMEOUT;
String productId = "123456";
if (!redisLock.lock(productId, String.valueOf(time))) {
logger.errorv("【商品id】:{},扣减库存失败,稍后从试");
}
//业务代码
//解锁
redisLock.unlock(productId, String.valueOf(time));
}
}