實驗3 控制語句與組合資料型別應用程式設計
阿新 • • 發佈:2022-04-20
資料庫
唯一索引、排他性
建表核心為業務防重複ID、鎖持有者ID
redis
redis單機是CP
單機不滿足高可用
public class WatchDogDemo { public static final String LOCKKEY = "AAA"; private static Config config; private static Redisson redisson; static { config = new Config(); config.useSingleServer().setAddress("redis://"+"192.168.111.147"+":6379").setDatabase(0); redisson = (Redisson)Redisson.create(config); } public static void main(String[] args) { RLock redissonLock = redisson.getLock(LOCKKEY); redissonLock.lock(); try { System.out.println("1111"); //暫停幾秒鐘執行緒 try { TimeUnit.SECONDS.sleep(25); } catch (InterruptedException e) { e.printStackTrace(); } }catch (Exception e){ e.printStackTrace(); }finally { redissonLock.unlock(); } System.out.println(Thread.currentThread().getName() + " main ------ ends."); //暫停幾秒鐘執行緒 try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } redisson.shutdown(); } }
redis叢集(主從模式)是AP
存在風險:主節點的資料還沒來得及同步給從節點就掛了
多主模式
N=2X+1個主節點,半數以上拿到鎖才行
redlock==>RedissonRedLock
public class RedLockController { public static final String CACHE_KEY_REDLOCK = "ZZYY_REDLOCK"; @Autowired RedissonClient redissonClient1; @Autowired RedissonClient redissonClient2; @Autowired RedissonClient redissonClient3; @GetMapping(value = "/redlock") public void getlock() { //CACHE_KEY_REDLOCK為redis 分散式鎖的key RLock lock1 = redissonClient1.getLock(CACHE_KEY_REDLOCK); RLock lock2 = redissonClient2.getLock(CACHE_KEY_REDLOCK); RLock lock3 = redissonClient3.getLock(CACHE_KEY_REDLOCK); RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3); boolean isLock; try { //waitTime 鎖的等待時間處理,正常情況下 等5s //leaseTime就是redis key的過期時間,正常情況下等5分鐘。 isLock = redLock.tryLock(5, 300, TimeUnit.SECONDS); log.info("執行緒{},是否拿到鎖:{} ",Thread.currentThread().getName(),isLock); if (isLock) { //TODO if get lock success, do something; //暫停20秒鐘執行緒 try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } } catch (Exception e) { log.error("redlock exception ",e); } finally { // 無論如何, 最後都要解鎖 redLock.unlock(); System.out.println(Thread.currentThread().getName()+"\t"+"redLock.unlock()"); } } }