1,概述:在一些高並發的場景中,比如秒殺,搶票,搶購這些場景,都存在對核心資源,商品庫存的爭奪,控制不好,庫存數量可能被減少到負數,出現超賣的情況,或者 產生唯一的一個遞增ID,由於web應用部署在多個機器上,簡單的同步加鎖是無法實現的,給數據庫加鎖的話,對於高並發,1000/s的並發,數據庫可能由行鎖變成表鎖,性能下降會厲害。那相對而言,redis的分布式鎖,相對而言,是個很好的選擇,redis官方推薦使用的Redisson就提供了分布式鎖和相關服務。
下面介紹下如何使用Redisson。
2,Redisson的使用方式十分簡單,詳見官方文檔:https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95
3,加入jar包的依賴:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>2.7.0</version>
</dependency>
4,配置Redisson
public class RedissonManager { private static Config config = new Config(); //聲明redisso對象 private static Redisson redisson = null; //實例化redisson
static{
config.useSingleServer().setAddress("127.0.0.1:6379");
//得到redisson對象
redisson = (Redisson) Redisson.create(config);
}
//獲取redisson對象的方法 public static Redisson getRedisson(){ return redisson; } }
5,鎖的獲取和釋放
public class DistributedRedisLock { //從配置類中獲取redisson對象 private static Redisson redisson = RedissonManager.getRedisson(); private static final String LOCK_TITLE = "redisLock_"; //加鎖 public static boolean acquire(String lockName){ //聲明key對象 String key = LOCK_TITLE + lockName; //獲取鎖對象 RLock mylock = redisson.getLock(key); //加鎖,並且設置鎖過期時間,防止死鎖的產生 mylock.lock(2, TimeUnit.MINUTES); System.err.println("======lock======"+Thread.currentThread().getName()); //加鎖成功 return true; } //鎖的釋放 public static void release(String lockName){ //必須是和加鎖時的同一個key String key = LOCK_TITLE + lockName; //獲取所對象 RLock mylock = redisson.getLock(key); //釋放鎖(解鎖) mylock.unlock(); System.err.println("======unlock======"+Thread.currentThread().getName()); } }
6,業務邏輯中使用分布式鎖
@RequestMapping("/redder")
@ResponseBody
public String redder() throws IOException{
String key = "test123";
//加鎖
DistributedRedisLock.acquire(key);
//執行具體業務邏輯
dosoming
//釋放鎖
DistributedRedisLock.release(key);
//返回結果
return soming;
}
