Spring定时任务的多次调用

发布于 2024-09-30 04:30:14 字数 2524 浏览 3 评论 0原文

因此,我使用 Spring 的 @Scheduled 注释声明的一些计划任务遇到了一些问题。首先是我的应用程序配置:

<beans <!--Namespaces-->>
    <!-- Search for annotated beans -->
    <context:component-scan  base-package="com.my.package.task"/>

    <task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>

    <task:executor id="myExecutor" pool-size="5"/>

    <task:scheduler id="myScheduler" pool-size="10"/>

    <tx:annotation-driven/>
</beans>

我还有一个 AppConfig 类:

@Configuration
@ImportResource("classpath:/config/app-config.xml")
public class AppConfig {
     //Bean declarations but NO references to the Scheduled tasks or their classes
}

这是我声明的计划任务:

public abstract class ScheduledTask {
     private ApplicationContext appContext;

     abstract void doSomething();

     protected getAppContext() {
          if(appContext == null) {
               appContext = new AnnotationConfigApplicationContext(AppConfig.class);
          }

          return appContext;
     }
     //Other common methods
}

@Service
public class Task1 extends ScheduledTask {    
     @Scheduled(cron="0 0 9 * * MON-FRI")
     public void doSomething() {
        System.out.println("Task1 -- Thread ID: " + Thread.currentThread().getId() + " Thread Name: " + Thread.currentThread().getName());
         //Update the database with new values
     }
}

@Service
public class Task2 extends Scheduledtask {
     @Scheduled(cron="0 0 10 * * MON-FRI")
     public void doSomething() {
          System.out.println("Task2 -- Thread ID: " + Thread.currentThread().getId() + " Thread Name: " + Thread.currentThread().getName());
          //Get some data from database and send email with data from DB
     }
}

现在我遇到的问题是,当这些任务运行时,我会收到多封电子邮件(请参阅任务2)。我在打印语句中添加了这些方法,以查看这些方法是否被多次调用,并且 Task2 是否被 2 个不同的线程执行了两次。我希望 Spring 只调用一次计划任务。这是我得到的输出:

Task1 -- Thread ID: 10 Thread Name: myScheduler-1
Task2 -- Thread ID: 23 Thread Name: myScheduler-2
Task2 -- Thread ID: 11 Thread Name: myScheduler-2 

如果我在晚上运行它并将 cron 作业设置为间隔 4 小时,我就会开始收到更多的电子邮件(我想我没有机会看看这是否是由于多线程/方法造成的)来电)。

有谁知道什么可能导致第二个任务的多次调用?我查看了 Spring 文档 并在“注意”下提到,如果在运行时初始化 @Scheduled 类的多个实例,则可以获得多次调用。我的 AppConfig 和 app-config.xml 是否会发生这种情况?

So I am having a bit of a problem with some scheduled tasks I have declared using Spring's @Scheduled annotation. First off here is my app-config:

<beans <!--Namespaces-->>
    <!-- Search for annotated beans -->
    <context:component-scan  base-package="com.my.package.task"/>

    <task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>

    <task:executor id="myExecutor" pool-size="5"/>

    <task:scheduler id="myScheduler" pool-size="10"/>

    <tx:annotation-driven/>
</beans>

I also have a AppConfig class:

@Configuration
@ImportResource("classpath:/config/app-config.xml")
public class AppConfig {
     //Bean declarations but NO references to the Scheduled tasks or their classes
}

And here are the scheduled tasks I have declared:

public abstract class ScheduledTask {
     private ApplicationContext appContext;

     abstract void doSomething();

     protected getAppContext() {
          if(appContext == null) {
               appContext = new AnnotationConfigApplicationContext(AppConfig.class);
          }

          return appContext;
     }
     //Other common methods
}

@Service
public class Task1 extends ScheduledTask {    
     @Scheduled(cron="0 0 9 * * MON-FRI")
     public void doSomething() {
        System.out.println("Task1 -- Thread ID: " + Thread.currentThread().getId() + " Thread Name: " + Thread.currentThread().getName());
         //Update the database with new values
     }
}

@Service
public class Task2 extends Scheduledtask {
     @Scheduled(cron="0 0 10 * * MON-FRI")
     public void doSomething() {
          System.out.println("Task2 -- Thread ID: " + Thread.currentThread().getId() + " Thread Name: " + Thread.currentThread().getName());
          //Get some data from database and send email with data from DB
     }
}

Now the problem I am getting is that when these tasks are run, I get multiple emails sent (see Task2). I added in the print statements to see if the methods were being called multiple times and Task2 is executed twice by 2 different threads. I would hope that Spring would only invoke a scheduled task once. Here is the output I get:

Task1 -- Thread ID: 10 Thread Name: myScheduler-1
Task2 -- Thread ID: 23 Thread Name: myScheduler-2
Task2 -- Thread ID: 11 Thread Name: myScheduler-2 

And if I run it at night and set the cron jobs to be like 4hrs apart I start to get even more emails sent (thought I havent had a chance to see if this is due to multiple threads / method calls).

Does anyone have any ideas what could be causing the multiple invocations of the second task? I looked at the Spring Documentation and under the 'Note' it mentions that you can get multiple invocation if you initialize multiple instances of the @Scheduled class at runtime. Could that be happening here with my AppConfig and app-config.xml?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文