redis 分布式锁的简单使用
2012 年 1 月 11 日
RedisLock——让 Redis 分布式锁变得简单
目录
1. 项目介绍
该项目主要简化了使用 redis 分布式事务所的操作,实现傻瓜式加锁,释放锁的操作,并优雅的实现了等待锁释放的操作。等待锁释放的过程主要是使用了redis的监听功能,所以在使用该项目前,要确保redis已经开启了key事件监听,即“Ex”。
-
如何查看 redis 是否已经开启了监听功能?
登录 redis 后,使用命令
config get notify-keyspace-events
进行查看
github地址: https://github.com/chimmhuang/redislock
码云地址: https://gitee.com/chimmhuang/redislock
欢迎 Start、Fork~
2. 快速使用
2.1 引入 maven 坐标
com.github.chimmhuang redislock 1.0.2
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 : chimmhuang@163.com
5. 开源协议
MIT © Chimm Huang