我们现在较少使用RedisTemplate 提供的setIfAbsent 做分布式锁,解决并发场景问题,一般使用成熟的三方工具Redisssion来解决分布式锁问题.但是有时候还是需要手动通过RedisTemplate 提供的setIfAbsent实现简化的分布式锁.
此处记录一下使用RedisTemplate 的 setIfAbsent 做分布式锁出现返回值为 null 的问题和解决方法.
1.场景描述
防止短时间内重复点击操作,多个请求对应着多个线程同时操作同一共享资源导致的线程安全问题.
见如下实现
(1).扣减金额操作
/**
* @desc 扣减金额
**/
@Transactional
public ResultBean<Boolean> reduceAmount(ReduceAmountReq request, UserData userData) {
Long id = request.getId();
// 防止重复扣除金额操作
String lockKey = RedisConstant.MEMBER_UPDATE_BALANCE + id;
boolean isLock = redisToolsService.tryLock(6 * 60 * 60, lockKey);
if (!isLock) {
// 获取锁失败 直接返回
return new ResultBean<>(Boolean.TRUE);
}
try {
// 用代理对象调用方法 spring事务通过代理对象来实现 这样就可以保证spring事务不会失效