目录
使用场景
推送账单功能,不允许多人同时操作同一个账单数据。
如果不使用分布式锁的弊端
在某些特定的场景,通常需要通过加锁来限制,系统使用人员对于某些数据的操作。如果不加限制,则会导致出现一批数据不同的人同时操作,导致数据出现问题,尤其涉及到金额相关的操作一定要加锁限制。
Maven依赖
在pom.xml中引入改依赖,则可以使用redis分布式锁。
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.11.4</version>
</dependency>
工具类RedissonClient
RedissonClient 是 Redisson 提供的一个接口,用于与 Redis 进行交互。Redisson 是一个用于 Java 的 Redis 客户端,它提供了许多功能强大的特性,例如分布式对象、分布式锁、分布式集合等,使得在 Java 应用中使用 Redis 变得更加方便。
代码引用片段
在项目中如何使用该工具类
通过与Service相似的方式注入进服务,即可当做Service来使用。
实际操作过程中,在加锁之前还需要进行业务逻辑校验,遍历业务数据加锁时需要用 数据的唯一性字段作为key,执行加锁操作,当项目有其他人员操作改数据时会提示加锁失败,此时只需要对数据做出指定的提示语句即可。
public void 同步订单 (){
//创建一个 RLock list 用于存储加锁之后产生的锁信息,方便后面进行解锁操作
List<RLock> lockList = new ArrayList<>();
try {
for (OmsOrderDTO omsOrderDTO : omsOrderDTOList) {
// 加锁处理
RLock lock = redissonClient.getLock(TMSLockUtils.getOrderLockKey(omsOrderDTO.getCode()));
if (!lock.tryLock()) {
log.info("TMS接收OMS下发订单::加锁失败::OmsOrderNo:{}", omsOrderDTO.getOrderNo());
throw new ServiceException("订单[" + omsOrderDTO.getOrderNo() + "]正在进行其他操作,请稍后重试!");
}
//将锁添加到 lockList中保存记录。
lockList.add(lock);
}
} finally {
try {
if (CollectionUtil.isNotEmpty(lockList)) {
//遍历加锁信息List 同时进行解锁操作
lockList.forEach(lock -> {
if (null != lock && lock.isLocked()) {
//解锁
lock.unlock();
}
});
}
} catch (Exception e) {
log.error("TMS接收OMS订单批量下发::解锁异常,", e);
}
}
}
温馨小提示
在使用redis分布式锁,加锁数据时,一定要记得搭配使用try catch finally , finally里面进行解锁操作,以防数据回退需要重新操作。还有一点就是如果不释放锁会导致redis压力加大,影响其使用性能。