在Spring中實現Redis分布式鎖可以使用RedisTemplate來操作Redis進行加鎖和解鎖。
首先,我們需要定義一個分布式鎖的實體類,包含鎖的名稱和鎖的過期時間:
public class RedisLock {
private String name; // 鎖名稱
private long expireTime; // 鎖的過期時間
// 構造方法和Getter/Setter省略
}
接下來,我們可以創建一個工具類來實現加鎖和解鎖的邏輯:
@Component
public class RedisLockUtil {
private static final String LOCK_PREFIX = "redis_lock_"; // 鎖的前綴
private static final long DEFAULT_EXPIRE_TIME = 30000L; // 默認鎖的過期時間
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 加鎖
* @param lockName 鎖的名稱
* @return 加鎖成功返回true,否則返回false
*/
public boolean lock(String lockName) {
String key = LOCK_PREFIX + lockName;
RedisLock redisLock = new RedisLock(key, DEFAULT_EXPIRE_TIME);
ValueOperations<String, Object> operations = redisTemplate.opsForValue();
Boolean absent = operations.setIfAbsent(key, redisLock);
if (absent != null && absent) {
return true; // 加鎖成功
}
// 判斷鎖是否過期
RedisLock currentLock = (RedisLock) operations.get(key);
if (currentLock != null && currentLock.getExpireTime() < System.currentTimeMillis()) {
RedisLock newLock = new RedisLock(key, DEFAULT_EXPIRE_TIME);
RedisLock oldLock = (RedisLock) operations.getAndSet(key, newLock);
if (oldLock != null && oldLock.getExpireTime() < System.currentTimeMillis()) {
return true; // 加鎖成功
}
}
return false; // 加鎖失敗
}
/**
* 解鎖
* @param lockName 鎖的名稱
*/
public void unlock(String lockName) {
String key = LOCK_PREFIX + lockName;
redisTemplate.delete(key);
}
}
使用示例:
@Service
public class MyService {
@Autowired
private RedisLockUtil redisLockUtil;
public void doSomething() {
// 加鎖
boolean locked = redisLockUtil.lock("myLock");
if (locked) {
try {
// 執行業務邏輯
} finally {
// 解鎖
redisLockUtil.unlock("myLock");
}
} else {
// 加鎖失敗,處理業務邏輯
}
}
}
在以上示例中,RedisLockUtil
定義了一個lock
方法來進行加鎖操作,使用setIfAbsent
方法嘗試將鎖的值存入Redis,如果返回值為true表示加鎖成功。如果加鎖失敗,則判斷當前鎖是否已經過期,如果過期則使用getAndSet
方法嘗試更新鎖的值,并判斷返回的舊值是否已經過期,如果過期表示加鎖成功。最后,unlock
方法通過刪除鎖的鍵來釋放鎖。