Java 如何在JEE集群上每晚运行方法

Java 如何在JEE集群上每晚运行方法,java,jakarta-ee,glassfish,Java,Jakarta Ee,Glassfish,我有一个Java EE应用程序在集群环境中的Glassfish 3.1.2上运行 我希望每天执行一次特定的方法(即从数据库中删除一些条目) 我创建了一个计时器: @Singleton public class TimerService { @Schedule(second = "0", minute = "0", hour = "0", persistent=false) public void runEveryDay() { LOG.info("### runE

我有一个Java EE应用程序在集群环境中的Glassfish 3.1.2上运行

我希望每天执行一次特定的方法(即从数据库中删除一些条目)

我创建了一个计时器:

@Singleton
public class TimerService {
    @Schedule(second = "0", minute = "0", hour = "0", persistent=false)
    public void runEveryDay() {
        LOG.info("### runEveryDay");
    }   
当我查看日志时,该方法会在两个集群节点上执行。我担心在两个节点上同时执行该方法时,可能会因为过时的数据而遇到问题


有没有办法只在一个节点上执行该方法?或者我可以以某种方式同步这些方法吗?

您可以通过使用预加载的数据库行作为事务锁来防止并发执行

编写一个JobLockService,如下所示:

@Stateless
public class JobLockService {

     @Resource
     private DataSource serializableDS;

     @TransactionAttribute(REQUIRES_NEW)
     public boolean jobLockAcquired() {
          // select jobLock record for update when flag = 0 and set flag
          return true if record selected otherwise false
     }

     @TransactionAttribute(REQUIRES_NEW)
     public void releaseJobLock() {
          // reset jobLock record flag back to 0
     }

}
然后将其提供给您的单身人士:

@Singleton
public class TimerService {

    @EJB
    private JobLockService jobLockService;

    @Schedule(second = "0", minute = "0", hour = "0", persistent=false)
    public void runEveryDay() {
        if (jobLockService.jobLockAcquired()) {
            try {
                 LOG.info("### runEveryDay");
            } finally {
                 jobLockService.releaseJobLock();
            }
        } else {
            log.info("Job already running elsewhere");
        }
    }
在服务器中配置一个特殊的数据源,该数据源的事务隔离级别设置为,以防止并发问题。(您通常不会使用此设置,因为它的高负载并发性能很差)


在JobLockService方法上使用事务将防止阻塞问题。

将计时器设置为持久性。然后,它应该只在集群中的一个服务器节点上执行

我也有这个问题。更好的解决方案是将每夜批处理与javaee容器分开安排,由操作系统安排。