1,概述:在一些高併發的場景中,好比秒殺,搶票,搶購這些場景,都存在對核心資源,商品庫存的爭奪,控制很差,庫存數量可能被減小到負數,出現超賣的狀況,或者 產生惟一的一個遞增ID,因爲web應用部署在多個機器上,簡單的同步加鎖是沒法實現的,給數據庫加鎖的話,對於高併發,1000/s的併發,數據庫可能由行鎖變成表鎖,性能降低會厲害。那相對而言,redis的分佈式鎖,相對而言,是個很好的選擇,redis官方推薦使用的Redisson就提供了分佈式鎖和相關服務。
下面介紹下如何使用Redisson。git
2,Redisson的使用方式十分簡單,詳見官方文檔:https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95github
3,加入jar包的依賴:web
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>2.7.0</version> </dependency>
4,配置Redissonredis
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; }