概述:在一些高并发的场景中,比如秒杀,抢票,抢购这些场景,都存在对核心资源,商品库存的争夺,控制不好,库存数量可能被减少到负数,出现超卖的情况,或者 产生唯一的一个递增ID,由于web应用部署在多个机器上,简单的同步加锁是无法实现的,给数据库加锁的话,对于高并发,1000/s的并发,数据库可能由行锁变成表锁,性能下降会厉害。那相对而言,redis的分布式锁,相对而言,是个很好的选择,redis官方推荐使用的Redisson就提供了分布式锁和相关服务。 平台默认集成redisson,只是没有使用,先将具体使用代码说明如下,共大家参考学习。
使用方式:
1、在需要添加同步控制的业务对象中,首先引入
@Autowired
private RedissonClient redissonClient;
2、在具体业务方法上创建锁对象
//getLock中的参数是自己根据业务拼接的字符串,整个系统中如果遇到相同字符串的锁定变量信息,将同步处理。
RLock lock = redissonClient.getLock(${锁定变量});
3、对同步块采用封装处理
try {
//尝试获取锁,如果超过10秒,进入异常流程
if(lock.tryLock(10, TimeUnit.SECONDS)){
try{
//获得锁,进行业务处理(处理过程中同样的SceneType.VALIDATE_MOBILE.name()+uuid 值在全局内不能再次进入,保证同步性)
//业务代码块
}catch(Exception e){
//业务报错异常处理分支
} finally {
lock.unlock();// 释放锁
}
}else{
//获取锁超时处理分支
//可以返回可控的处理信息 例如:"系统繁忙,请过后尝试!"
}
} catch (InterruptedException e) {
// trylock 线程阻塞Interrupt
// 静默处理!
}
使用注意事项:
1、使用锁的目的是使业务同步化,这样在技术上就要求每次锁的部分执行效率很高,要不就会有严重的性能问题,所以使用锁的块要尽量控制合理。
2、锁的代码主要针对业务代码,所以锁块要求加载@Service对象对应的业务方法上。
3、锁的key(锁定变量)要合理规划,避免锁范围超过业务范围,造成不必要的性能问题。
共同学习,写下你的评论
评论加载中...
作者其他优质文章