實現思路如下:
1.數據庫中設計一個表有如下字段:
鎖的key,鎖的生效時間,鎖的過期時間,鎖的類型,獲取到鎖的機器IP地址】
2、然後把鎖的key和鎖的類型 作爲一個索引 類型爲unique 唯一的。
3、在上鎖的時候就是往其中插入數據的時候,由於有一個唯一索引所以插入數據只會有一個成功,即搶到鎖的上鎖的那個程序。
如果插入失敗,查詢已經存在的鎖的過期時間是否小於了當前要插入的鎖的生效時間 ,查詢爲空說明該鎖未過期,查詢不爲空說明該鎖已經過期,可以進行更新鎖的生效時間和過期時間了。
4、執行問完之後就刪除該條數據釋放鎖。
僞代碼如下:
public boolean lock(String lockKey, String lockType, long lockTime) { try { ConnLock connLock = new ConnLock(); connLock.setLockKey(lockKey); connLock.setLockType(lockType); connLock.setLockIp(IpUtils.getLocalIP()); Long effectiveTime = System.currentTimeMillis(); Long expiredTime = effectiveTime + lockTime; connLock.setEffectiveTime(effectiveTime); connLock.setExpiredTime(expiredTime); try { if (connLockDao.insert(connLock) > 0) { return true; } } catch (Exception e) { LOGGER.error("insert lock data fail! key:{}, type:{}", lockKey, lockType); } connLock = connLockDao.selectExpLockByKeyAndType(lockKey, lockType, effectiveTime); if (connLock == null) { LOGGER.info("can not find expired lock by key:{} and type:{},curTime is {}", lockKey, lockType, effectiveTime); return false; } if (connLockDao.updateExistLock(effectiveTime, expiredTime, connLock.getEffectiveTime(), connLock.getId()) > 0) { return true; } LOGGER.info("update expired lock fail by key:{} and type:{},curTime is {}", lockKey, lockType, effectiveTime); } catch (Exception e) { LOGGER.warn("get lock exception,lockKey is : {},lockType is : {}", lockKey, lockType, e); } return false; }