redis 分佈式鎖的簡單使用

RedisLock——讓 Redis 分佈式鎖變得簡單

lisence
jdk

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 使用

  1. 注入 redisLock
  2. 使用 redisLock.lock(key,expire) 進行加鎖
  3. 使用 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