redis 分佈式鎖的簡單使用
RedisLock——讓 Redis 分佈式鎖變得簡單
1. 項目介紹
該項目主要簡化了使用 redis 分佈式事務所的操作,實現傻瓜式加鎖,釋放鎖的操作,並優雅的實現了等待鎖釋放的操作。等待鎖釋放的過程主要是使用了redis的監聽功能,所以在使用該項目前,要確保redis已經開啟了key事件監聽,即「Ex」。
- 如何查看 redis 是否已經開啟了監聽功能?
登錄 redis 後,使用命令config get notify-keyspace-events
進行查看
github地址://github.com/chimmhuang/redislock
碼雲地址://gitee.com/chimmhuang/redislock
歡迎 Start、Fork~
2. 快速使用
2.1 引入 maven 坐標
<dependency>
<groupId>com.github.chimmhuang</groupId>
<artifactId>redislock</artifactId>
<version>1.0.2</version>
</dependency>
2.2 註冊 RedisLock
- 方式一(推薦): 在項目的啟動類上添加包掃描的路徑
@ComponentScan(basePackages = "com.github.chimmhuang.redislock")
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 方式二:手動註冊相關的 bean
@Configuration
public class RedisConfig {
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
@Bean
public RedisListener redisListener(RedisMessageListenerContainer redisMessageListenerContainer) {
return new RedisListener(redisMessageListenerContainer);
}
@Bean
public RedisLock redisLock(RedisTemplate redisTemplate) {
return new RedisLock(redisTemplate);
}
}
2.3 使用
- 注入
redisLock
- 使用
redisLock.lock(key,expire)
進行加鎖 - 使用
redisLock.unlock(key)
進行解鎖
以下提供一個單元測試的案例(火車站賣票的案例)
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisListenerTest {
@Autowired
private RedisLock redisLock;
/** 100張票 */
private static Integer count = 100;
@Test
public void ticketTest() throws Exception {
TicketRunnable tr = new TicketRunnable();
// 四個線程對應四個窗口
Thread t1 = new Thread(tr,"窗口A");
Thread t2 = new Thread(tr,"窗口B");
Thread t3 = new Thread(tr,"窗口C");
Thread t4 = new Thread(tr,"窗口D");
t1.start();
t2.start();
t3.start();
t4.start();
Thread.currentThread().join();
}
public class TicketRunnable implements Runnable {
@Override
public void run() {
while (count > 0) {
redisLock.lock("ticketLock", 3L);
if (count > 0) {
System.out.println(Thread.currentThread().getName() + "售出第" + (count--) + "張火車票");
}
redisLock.unlock("ticketLock");
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
3. 參與貢獻
非常歡迎你的加入!提一個 Issue 或者提交一個 Pull Request。
目前僅僅是實現了加鎖解鎖的簡單過程,還有其他操作有待完善和測試,如:
-[ ] 在 redis 的集群環境中,需要監聽每一個 redis 的 key 事件
-[ ] 在 redis 的主備模式下,可能會存在主備 redis 切換的期間,數據(key)未同步過去問題
4. 聯繫作者
QQ(Wechat) : 905369866
Email : [email protected]
5. 開源協議
MIT © Chimm Huang