背景
操作涉及一批數據,如訂單,可能存在多個場景下操作,先使用讀鎖,從redis緩存中獲取操作中數據
比如
關閉賬單,
發起調賬,
線下結算,
合并支付
先判斷當前操作的數據,是否在其他地方操作中(在redis set結構中),
存在:提示稍后再操作,業務流程終止。
不存在:把當前操作數據放入redis 緩存中(同時這個動作加寫鎖),在加寫鎖的過程中,是不允許其他讀鎖讀取數據的
然后,進行業務邏輯處理
什么把緩存中數據刪除呢?
操作完成,刪除緩存中數據(同時加寫鎖)
/*** 刪除操作完成的賬單號緩存** @param billNoList*/public void removeInOperationBillNoCache(List<String> billNoList) {log.info("removeInOperationBillNoCache--->billNoList:{}", JSON.toJSONString(billNoList));RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(Constant.LEASE_BILL_IN_OPERATION_KEY);RLock writeLock = readWriteLock.writeLock();writeLock.lock();try {billNoList.forEach(billNo -> redisService.srem(Constant.LEASE_BILL_IN_OPERATION_CACHE, billNo));} finally {writeLock.unlock();}}
?判斷及讀寫鎖邏輯
/*** 緩存操作中的賬單號** @param billNoList*/@SuppressWarnings("unchecked")public void inOperationBillNoCache(List<String> billNoList) {log.info("inOperationBillNoCache--->billNoList:{}", JSON.toJSONString(billNoList));RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(Constant.LEASE_BILL_IN_OPERATION_KEY);RLock rLock = readWriteLock.readLock();rLock.lock();try {if (redisService.hasKey(Constant.LEASE_BILL_IN_OPERATION_CACHE)) {Set<String> inOperationBillNoSet = redisService.smembers(Constant.LEASE_BILL_IN_OPERATION_CACHE);log.info("inOperationBillNoCache--->inOperationBillNoSet:{}", JSON.toJSONString(inOperationBillNoSet));if (CollectionUtils.isNotEmpty(inOperationBillNoSet)) {List<String> multipleOperationBillNoList = (List<String>) CollectionUtils.intersection(inOperationBillNoSet, billNoList);throw new LeaseServiceException(ErrConstant.INVALID_DATAFILED, String.format("賬單[%s]存在多人操作,請刷新后重試", String.join(",", multipleOperationBillNoList)));}}} finally {rLock.unlock();}RLock writeLock = readWriteLock.writeLock();writeLock.lock();try {billNoList.forEach(billNo -> redisService.sadd(Constant.LEASE_BILL_IN_OPERATION_CACHE, billNo));} finally {writeLock.unlock();}}
調用場景?
關于緩存數據redis結構選取
set,數據不重復,可以計算交集,判斷是否在當前元素中?
源碼
?