背景:同事开发一个扫码活动。需要处理并发扫一个码的问题。采用redison分布式锁处理。锁生效了,但是并发扫码没控制住。
我推荐他使用:
1 乐观锁
2 处理扫码业务代码块 提炼成方法,这个方法加上事务。而不是把分布式锁放在事务里面。
@Transactional(rollbackFor = Exception.class)
public ScanQrCodeResultVO execScanQrCode(...){
// 校验
// 业务代码加锁
RLock lock = redissonClient.getSpinLock("key");
try {
//判断是否被扫
//扫码发放奖励
} catch (Exception e) {
//
} finally {
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
修改成
public ScanQrCodeResultVO execScanQrCode(...){
// 校验
// 业务代码加锁
RLock lock = redissonClient.getSpinLock("key");
try {
} catch (Exception e) {
handleScanCode(...)
} finally {
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
@Transactional(rollbackFor = Exception.class)
public void handleScanCode(...){
//判断是否被扫
//扫码发放奖励
}
后面排查到:
因为finally里面添加了解锁,而解锁后才会提交事务。导致后一个扫码查询不到前一个扫码的数据变更。