分布式锁在分布式应用场景我觉得是不可缺少的一部分,比如我们分布式系统中有俩个订单系统,那么如果2个用户同时去购买最后1件商品,在代码中可能出现同时减去最后一件库存并创建订单,这样有可能出现1个库存出现2个订单的现象,所以跟大家分享一下分布式锁Redisson的使用。
首先在springboot中引用pom文件
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.2</version>
</dependency>
配置application.yml如下
spring:
redis:
password: root
host: localhost
port: 6379
编写Redisson工具类如下,目的优化业务代码,方便快速调用使用,实现AutoCloseable接口的close方法,可以做程序执行完毕时调用关闭锁,以免我们代码中忘记关闭的操作。
这里贴出代码
@Slf4j
public class RedissonLock implements AutoCloseable{
//获取锁
private RLock rLock;
private RedissonClient redissonClient;
public RedissonLock(RedissonClient redissonClient){
this.redissonClient = redissonClient;
}
/**
* @param name 自定义锁的名字
* @param seconds redisson设置订单时间,单位秒
* */
public void getRedissonLock(String name,int seconds){
rLock = redissonClient.getLock(name);
//设置锁等待时间,这里30秒为例
this.rLock.lock(seconds, TimeUnit.SECONDS);
}
@Override
public void close() throws Exception {
log.info("我释放了锁!");
rLock.unlock();
}
}
我们在service使用时,如下引用
直接try()中创建我们自己定义的工具类,这样配合AutoCloseable可在最后调用close方法自动关闭锁。
@Service
@Slf4j
public class RedissonServiceImpl implements IRedissonService {
@Autowired
private RedissonClient redissonClient;
@Override
//由于事务只能捕捉运行时异常,执行代码可能出现抛出异常现象,需加rollbackFor捕捉回滚
@Transactional(rollbackFor = Exception.class)
public void redisson() {
log.info("我进入方法!");
//根据名称返回锁的实例
try(RedissonLock redissonLock = new RedissonLock(redissonClient)){
redissonLock.getRedissonLock("order",30);
log.info("我获得了锁!");
//执行代码
Thread.sleep(10000);
}catch (Exception e){
e.printStackTrace();
}
}
}
这样我们就已经完成锁的使用,我们来测试一下,分别启动8080、8081端口
运行结果如下。
8080端口 8081端口我们可以看出当8080执行整个过程后释放锁的时间,正好是8081获得锁时间,也就说明了8080执行完成后,我们的8081才开始执行,这样避免出现并发的可能。
本人初学者,想与各位分享所学的知识,如有错误或不足之处,望见谅!谢谢!
网友评论