1. 程式人生 > 資料庫 >Redis分散式事務鎖之核心程式碼

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")

public String deductStock() throws InterruptedException {
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)
//stringRedisTemplate.expire(lockKey,30, TimeUnit.SECONDS);
/*Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);

if (!result) {
return "1001";
}*/

// 加鎖,實現鎖續命功能
redissonLock.lock();

int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock")); // jedis.get("stock")
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";
}

}