簡體   English   中英

如何在JEE Cluster上每晚運行方法

[英]How to run method every night on JEE Cluster

我在一個集群環境中運行Glassfish 3.1.2上的Java EE應用程序。

我想每天執行一次特定的方法(即從數據庫中刪除一些條目)。

我創建了一個Timer:

@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");
        }
    }

在服務器中配置一個特殊的數據源,該數據源配置為將其事務隔離級別設置為TRANSACTION_SERIALIZABLE ,以防止出現並發問題。 (您通常不會使用此設置,因為它的高負載並發性能很糟糕)

在JobLockService方法上使用REQUIRES_NEW事務可以防止阻塞問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM