如何正确实施redis分布式锁

如何正确实施redis分布式锁

   点关注不迷路,欢迎再访!		

精简博客内容,尽量已行业术语来分享。
努力做到对每一位认可自己的读者负责。
帮助别人的同时更是丰富自己的良机。

应用场景

集群下部署多个应用,定时任务就会出现重复执行的问题,为了避免资源浪费和脏数据的问题出现,借助redis分布式锁解决

redis实现分布式锁用到的几个命令:setnx、get、getset、expire
在这里插入图片描述

redis分布式锁实现

基于Redis实现的分布式锁其实很简单,底层就是使用redis的setnx指令来实现的加锁,我们来看看官方对setnx的定义:
SETNX key value
将 key 的值设为 value ,当且仅当 key 不存在。
若给定的 key 已经存在,则 SETNX 不做任何动作。

死锁问题

既然setnx这么强大,还需考虑一些极端场景。
比如如果一台机器在运行状态中突然宕机没有设置锁的过期时间无法自动释放锁,那么另一台应用会一直认为有机器占用着分布式锁执行任务,此时实际是没有执行的,而导致死锁问题。

死锁问题解决方法

在这里我们给分布式锁设置一个过期时间,能够在开始执行任务后自动释放分布式锁

具体实现代码

/**
 * @author ex_sunqi
 * 分布式锁控制schedule
 */
@Component
@Configuration
@EnableScheduling
public class fileScheduleTask {
	    
	private final Log logger = LogFactory.getLog(getClass());	  
	private static final String LOCK = "job-lock";
    private static final String KEY = "fileTasklock";
    //单位为秒  默认10分钟
    private long redis_time = 60 * 10;

	    @Scheduled(cron = "0 0/30 * * * ?")
	    public void fileConvertJob() {
	        boolean lock = false;
	        try {
	            lock = redisTemplate.opsForValue().setIfAbsent(KEY, LOCK);
	            logger.info("是否获取到锁:" + lock);
	            if (lock) {
	            	//设置分布式锁的过期时间
                    redisTemplate.expire(KEY, redis_time , TimeUnit.SECONDS);
	            	//代码核心逻辑  
	            	      		
	            } else {
	                logger.info("没有获取到锁,不执行任务!");
	                return;
	            }
	        } finally {
	            if (lock) {
	                redisTemplate.delete(KEY);
	                logger.info("任务结束,释放锁!");
	            } else {
	                logger.info("没有获取到锁,无需释放锁!");
	            }
	        }

	    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值