首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring Shedlock不能保证同步

Spring Shedlock不能保证同步
EN

Stack Overflow用户
提问于 2020-06-18 20:38:52
回答 2查看 714关注 0票数 1

我有以下计划的作业,在多个实例中运行。

代码语言:javascript
复制
@Scheduled(fixedRate = 10000)
@SchedulerLock(name = "AwesomeJob", lockAtLeastForString = "5S", lockAtMostForString = "5S")
public void awesomeJob() throws InterruptedException {

    for (int i = 0; i < 5; i++) {
        log.info("Processing {}", i);
        Thread.sleep(100000L);
    }
}

我知道,如果任务花费的时间比lockAtMostFor长,那么导致的行为可能是不可预测的。有没有办法通过使用SimpleLock.extend方法来避免这种行为?我正在使用JdbcLockProvider。我是从https://github.com/lukas-krecan/ShedLock/issues/151那里得到这个想法的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-19 13:36:35

最简单的方法是将lockAtMostFor设置为更高的值。它只是一个安全网,以防执行任务的节点死掉,所以这应该不是问题。

如果由于某些原因不能做到这一点,您可以使用extend方法,如您提供的问题中所述。但这意味着你必须手动管理锁。目前还没有允许扩展使用AOP自动创建的锁的功能。

票数 1
EN

Stack Overflow用户

发布于 2020-06-18 21:06:02

代码语言:javascript
复制
interface LockService {
   bool aquireLock(String lockKey, String value);
   bool releaseLock(String lockKey);
}

interface SomeService {
   void do();
}

class Scheduler{
    @AutoWired LockService lockService;
    @Autowired SomeService someService;
    @Scheduled(fixedRate = 10000)
    public void awesomeJob() throws InterruptedException {
      if(lockService.aquireLock("awesomeJob", serverId) ){
        try{
           //call service method 
            someService.do();
        }catch( Exception e ){
          //TODO
        }finally{
          lockService.releaseLock("awesomeJob");
        }
      }   
    }
}

您可以拥有一个像这样的锁,实现一个为给定服务提供锁的lock接口。一旦你有了LockService,就可以用它来限制函数的运行。

这样做的唯一问题是您需要将此代码块添加到所有函数。如果您不想将此代码块添加到所有函数中,那么可以添加一个基于注释的AOP处理程序。

另外,如果获得锁的服务器死了怎么办?我们需要设置每个锁的最大过期时间,或者在锁值中使用时间来识别它是何时添加的,根据锁时间来决定是否可以运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62450176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档