使用Redisson RLock锁防止定时任务短周期重复执行

简介: 在开发定时任务时,如果任务执行周期较短,可能会导致任务在前一次执行尚未完成时就再次触发,从而产生重复执行的问题。为了解决这个问题,我们可以借助Redisson的RLock锁机制,确保任务只有在前一次执行完成后才能再次执行。本文将介绍如何使用Redisson RLock锁来避免定时任务的重复执行。

RLock.jpg

在开发定时任务时,如果任务执行周期较短,可能会导致任务在前一次执行尚未完成时就再次触发,从而产生重复执行的问题。为了解决这个问题,我们可以借助Redisson的RLock锁机制,确保任务只有在前一次执行完成后才能再次执行。本文将介绍如何使用Redisson RLock锁来避免定时任务的重复执行。

定时任务是一种常见的自动化执行任务的方式,例如在一些app的工单展示中,我们可能需要从数据库中获取到已到生效时间的工单进行发布。然而,如果任务的执行时间超过了1分钟,就会导致任务在前一次执行尚未完成时再次触发,从而产生重复执行的问题。

为了解决这个问题,我们可以使用Redisson的RLock锁机制。Redisson是一个基于Redis的分布式Java对象和服务的框架,它提供了RLock作为分布式可重入锁的实现。RLock允许同一个线程多次获取锁,而不会产生死锁。

RLock介绍

RLock是Redisson提供的分布式可重入锁(Reentrant Lock)的实现。与Python中的RLock类似,Redisson的RLock也具有可重入特性,允许同一个线程多次获取同一把锁而不会产生死锁。

Redisson RLock的特点和使用方式如下:

  • 可重入性:RLock允许同一个线程多次获取锁,而不会导致死锁。每次获取锁时,计数器会递增,直到释放锁的次数与获取锁的次数相等,才会完全释放锁。
  • 高可用性:RLock通过Redis作为分布式锁的后端存储,因此具有良好的可扩展性和高可用性。即使某个Redis节点故障,也可以通过其他可用节点继续提供锁服务。
  • 锁超时机制:RLock支持自动过期释放锁的机制。如果一个线程获取锁后,由于某些原因没有及时释放锁,可以通过设置锁的超时时间来确保在一定时间后自动释放锁,避免长时间占用锁资源。
  • 公平锁:Redisson RLock支持公平锁机制,即在多个线程等待获取锁时,按照获取锁的顺序依次获得锁。这样可以避免线程饥饿的情况发生。
  • 锁续约:RLock支持锁的续约机制,即在获取锁后,可以通过设置锁的过期时间来延长锁的持有时间。这样可以避免因为某个线程持有锁时间过长导致其他线程等待超时。

示例代码

下面是使用Redisson RLock锁来避免定时任务重复执行的示例代码:

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class Task{
   
   
    //锁过期时间
    private static final Long LOCK_KEY_TIME = 120L;

    public void doJobTask() {
   
   
        //定时任务执行周期较短,为防止数据重复修改,加入锁
        RLock lock = redissonCache.getLock("your_task_name");
        // 尝试获取锁并设定锁的过期时间
        boolean acquired = false;
        try {
   
   
            acquired = lock.tryLock(0, LOCK_KEY_TIME, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
   
   
            log.error("取锁失败");
        }
        if (acquired) {
   
   
            try {
   
   
                // 执行业务逻辑
                handleTask();
            }catch (Exception e) {
   
   
                log.error("处理失败");
                //业务异常处理逻辑
                handleTaskError();
            }finally {
   
   
                // 释放锁
                lock.unlock();
            }

        } else {
   
   
            // 获取锁失败,说明有其他线程或进程正在处理数据
            // 可以进行重试或触发告警机制
            handleLockAcquisitionFailure();
        }
    }
}

在上述示例代码中,我们使用tryLock(0, LOCK_KEY_TIME, TimeUnit.SECONDS)方法来尝试获取锁。其中,等待时间为0秒,即如果锁被其他线程持有,当前线程不会阻塞,而是立即返回获取锁失败。锁的过期时间设置为LOCK_KEY_TIME秒,即如果获取锁后在指定时间内未释放锁,锁将自动过期释放。

通过使用tryLock方法,我们可以更灵活地控制锁的获取,避免任务在短周期内重复执行,并通过锁的过期时间确保锁的释放。

目录
相关文章
|
6月前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
7284 97
|
缓存 负载均衡 应用服务中间件
nginx配置域名转发、反向代理、负载均衡
本文是博主学习nginx的记录,希望对大家有所帮助。
3780 0
|
4月前
|
缓存 Dubbo Java
什么是API网关
API网关是一种架构思想,用于统一接收外部请求并转发至后端服务,实现协议转换、路由、鉴权、限流、熔断降级等功能。通过网关,可简化客户端调用,提升系统安全性与可维护性。常见实现如Kong、Zuul、Spring Cloud Gateway等,广泛应用于微服务架构中,支持异步处理、全链路监控与多维度流量控制。
|
监控 Java 数据库
Spring Boot中的多租户架构实现
Spring Boot中的多租户架构实现
|
监控 Java 数据库连接
详解Spring Batch:在Spring Boot中实现高效批处理
详解Spring Batch:在Spring Boot中实现高效批处理
2895 12
|
数据可视化 数据库 数据安全/隐私保护
在IDEA中如何用可视化界面操作数据库? 在idea中如何操作数据库? 在idea中如何像Navicat一样操作数据库?
文章介绍了如何在IDEA中使用可视化界面操作数据库,类似于Navicat,以提高数据库操作的效率和管理性。
576 1
在IDEA中如何用可视化界面操作数据库? 在idea中如何操作数据库? 在idea中如何像Navicat一样操作数据库?
|
消息中间件 Linux
RabbitMQ最大连接数
RabbitMQ最大连接数
1344 0
|
机器学习/深度学习 存储 人工智能
深度学习之不遗忘训练
基于深度学习的不遗忘训练(也称为抗遗忘训练或持久性学习)是针对模型在学习新任务时可能会忘记已学习内容的一种解决方案。该方法旨在使深度学习模型在不断接收新信息的同时,保持对旧知识的记忆。
465 4
RISC指令集比较
《基础系列》
1108 0
|
安全 Java
【Java集合类面试十六】、HashMap与ConcurrentHashMap有什么区别?
HashMap是非线程安全的,而ConcurrentHashMap通过减少锁粒度来提高并发性能,检索操作无需锁,从而提供更好的线程安全性和性能。

热门文章

最新文章

下一篇
开通oss服务