Redis use of setnx command to achieve
@Component @Slf4j public class RedisLock { @Autowired private StringRedisTemplate stringRedisTemplate; /** * 加锁 * * @param key * @param value * @return */ 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; } /** * 解锁 * @param key * @param value */ 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) { log.error("【redis分布式锁】 解锁异常,{}", e); } } }
demo
@Service public class SecKillServiceImpl implements SeckillService { //超时时间10秒 private static final int TIMEOUT = 10 * 1000; @Autowired private RedisLock redisLock; static Map<String, Integer> products; static Map<String, Integer> stock; static Map<String, String> orders; { products = new HashMap<>(); stock = new HashMap<>(); Orders = new new the HashMap <> (); products.put ( "123456", 100000 ); stock.put ( "123456", 100000 ); } Private String QueryMap (String the productId) { return "celebrations, egg soup cheap, Limited parts " + products.get (the productId) +" left: "+ stock.get (productId) + " parts " +" under the item number of successful single-user: " + orders.size () +" person " ; } @Override public void orderProductMockDiffUser(String productId) { Long time = System.currentTimeMillis() +TIMEOUT; // lock IF (! RedisLock.lock (productId, String.valueOf (Time))) { the throw new new SellException (101, "whoops Hey, too many people in try" ); } Integer stockNum = stock.get (the productId); IF (stockNum == 0 ) { the throw new new SellException (100, "end of the event" ); } the else { // single orders.put (KeyUtil.genUniqueKey (), the productId); // Stock Save stockNum stockNum = -. 1 ; the try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } stock.put(productId, stockNum); } //解锁 redisLock.unlock(productId, String.valueOf(time)); } @Override public String querySecKillProductInfo(String productId) { return queryMap(productId); } }