Redis分散式事務鎖之核心程式碼
分享一下最近學習Redis分散式事務鎖的核心程式碼,主要解決高併發情況下分散式事務的同步問題。
@RestController
public class IndexController {
private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
@Autowired
private Redisson redisson;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@RequestMapping("/deduct_stock")
String lockKey = "product_001";
//String clientId = UUID.randomUUID().toString();
RLock redissonLock = redisson.getLock(lockKey);
try {
//Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "zhuge"); //jedis.setnx(key,value)
/*Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);
if (!result) {
return "1001";
}*/
// 加鎖,實現鎖續命功能
redissonLock.lock();
if (stock > 0) {
int realStock = stock - 1;
stringRedisTemplate.opsForValue().set("stock", realStock + ""); // jedis.set(key,value)
System.out.println("扣減成功,剩餘庫存:" + realStock + "");
} else {
System.out.println("扣減失敗,庫存不足");
}
}finally {
redissonLock.unlock();
/*if (clientId.equals(stringRedisTemplate.opsForValue().get(lockKey))){
stringRedisTemplate.delete(lockKey);
}*/
}
return "end";
}
@RequestMapping("/redlock")
public String redlock() throws InterruptedException {
String lockKey = "product_001";
//這裡需要自己例項化不同redis例項的redisson客戶端連線,這裡只是虛擬碼用一個redisson客戶端簡化了
RLock lock1 = redisson.getLock(lockKey);
RLock lock2 = redisson.getLock(lockKey);
RLock lock3 = redisson.getLock(lockKey);
/**
* 根據多個 RLock 物件構建 RedissonRedLock (最核心的差別就在這裡)
*/
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
try {
/**
* 4.嘗試獲取鎖
* waitTimeout 嘗試獲取鎖的最大等待時間,超過這個值,則認為獲取鎖失敗
* leaseTime 鎖的持有時間,超過這個時間鎖會自動失效(值應設定為大於業務處理的時間,確保在鎖有效期內業務能處理完)
*/
boolean res = redLock.tryLock(10, 30, TimeUnit.SECONDS);
if (res) {
//成功獲得鎖,在這裡處理業務
}
} catch (Exception e) {
throw new RuntimeException("lock fail");
} finally {
//無論如何, 最後都要解鎖
redLock.unlock();
}
return "end";
}
}