【问题标题】:EJB Timer long running method and Weblogic 10.3.4 issuesEJB Timer 长时间运行方法和 Weblogic 10.3.4 问题
【发布时间】:2011-10-22 15:22:25
【问题描述】:

我有一个 EJB Timer 3.0,这个计时器有一个方法,每次调用大约运行 6 小时。我实现的定时器如下:

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class BatchJobConsumerTimer implements BatchJobConsumerTimerLocal {

@Resource
TimerService timerService;

@EJB
ModelOperationsLocal modelOperations;

private static final long ONE_DAY_IN_MILLISECONDS = 86400000L;

private static final Logger LOG = Logger
        .getLogger(BatchJobConsumerTimer.class);

public BatchJobConsumerTimer() {
}

@Timeout
public void timeout(Timer timer) {
    LOG.info("Entering timeout method.");
    if(TimerRunningChecker.isWorking()){
        LOG.warn("A TIMER ALREADY IS RUNNING, SECOND TIMER WANTS TO ENTER TIMEOUT METHOD");
        return;
    } else {
        TimerRunningChecker.setWorking(true);
    }

    TimerConfiguration timerConfiguration = (TimerConfiguration) timer
            .getInfo();
    if (timerConfiguration != null) {
        Calendar calendar = new GregorianCalendar();
        if (isWorkDay(timerConfiguration.getSelectedDays())) {
            Date startTime = new Date(System.currentTimeMillis());
            Boolean and = timerConfiguration.getAnd();
            Integer numberOfJobs = timerConfiguration.getNumberOfJobs();

            int jobConsumed = 0;

            INFINITE: while (true) {
                List<Job> findWaitingJobs = modelOperations
                        .getLatestUploadedWaitingBatchJobs((numberOfJobs == -1 || numberOfJobs > 100) ? 100
                                : numberOfJobs);
                if (findWaitingJobs != null) {
                    if(findWaitingJobs.size() == 0){
                        LOG.warn("There is no jobs to consume.");
                        break INFINITE;
                    }
                    for (Job job : findWaitingJobs) {
                        ++jobConsumed;// means successful and unsuccessful
                        LOG.info("Job Number: " + (jobConsumed));
                        if (and) {
                            if (numberOfJobs != -1) {

                                if (jobConsumed > numberOfJobs
                                        && isEqualsAfterEndSchedule(
                                                calendar,
                                                timerConfiguration)) {
                                    LOG.info("jobConsumed > numberOfJobs && isEqualsAfterEndSchedule(calendar) is true");
                                    break INFINITE;
                                }
                            } else {
                                if (isEqualsAfterEndSchedule(calendar,
                                        timerConfiguration)) {
                                    LOG.info("numberOfJobs = infinite && isEqualsAfterEndSchedule(calendar) is true");
                                    break INFINITE;
                                }
                            }
                        } else {
                            if (numberOfJobs != -1) {
                                if (jobConsumed > numberOfJobs
                                        || isEqualsAfterEndSchedule(
                                                calendar,
                                                timerConfiguration)) {
                                    LOG.info("jobConsumed > numberOfJobs || isEqualsAfterEndSchedule(calendar) is true");
                                    break INFINITE;
                                }
                            } else {
                                if (isEqualsAfterEndSchedule(calendar,
                                        timerConfiguration)) {
                                    LOG.info("numberOfJobs = infinite || isEqualsAfterEndSchedule(calendar) is true");
                                    break INFINITE;
                                }
                            }
                        }

                        try {
                            LOG.info(job.getServiceNumber()
                                    + " hizmet numarali is tuketilicek.");

                            modelOperations.update(job);
                        } catch (Exception e) {
                            LOG.error(e, e);
                        }
                    }
                } else {
                    // liste bos don method'dan
                    break INFINITE;
                }
            }

            //send email
            Date endTime = new Date(System.currentTimeMillis());
            try {
                modelOperations.sendBatchOperationMail(startTime, endTime);
            } catch (Exception e) {
                LOG.error(e, e);
            }
        } else {
            LOG.warn("Today is not the working day.");
        }
    } else {
        LOG.warn("TimerConfiguration is not set.");
    }

    if(!TimerRunningChecker.isWorking()){
        LOG.warn("A TIMER WANTS CHANGE THE STATE OF WORKING TO NOT WORKING STATE, BUT IT IS ALREADY SET NOT WORKING STATE");
        return;
    } else {
        TimerRunningChecker.setWorking(false);
    }
    LOG.info("Exiting timout method.");
}

@Override
public void createTimer(TimerConfiguration timerConfiguration)
        throws Exception {
    // stop the other timers.
    Collection<Timer> timers = timerService.getTimers();
    for (Timer timer : timers) {
        timer.cancel();
    }

    timerService.createTimer(
            getRemainingTimeToFirstExpiration(timerConfiguration),
            ONE_DAY_IN_MILLISECONDS, timerConfiguration);
}

private long getRemainingTimeToFirstExpiration(
        TimerConfiguration timerConfiguration) {
    Calendar now = new GregorianCalendar();
    Calendar nextStart = new GregorianCalendar();
    nextStart.set(Calendar.HOUR_OF_DAY, timerConfiguration.getBeginHour());
    nextStart.set(Calendar.MINUTE, timerConfiguration.getBeginMinute());
    nextStart.set(Calendar.SECOND, timerConfiguration.getBeginSecond());

    long diff = nextStart.getTimeInMillis() - now.getTimeInMillis();
    return (diff < 0 ? diff + ONE_DAY_IN_MILLISECONDS : diff);
}

private boolean isEqualsAfterEndSchedule(Calendar calendar,
        TimerConfiguration timerConfiguration) {
    calendar.setTimeInMillis(System.currentTimeMillis());
    int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
    int currentMinute = calendar.get(Calendar.MINUTE);
    int currentSecond = calendar.get(Calendar.SECOND);

    if (currentHour > timerConfiguration.getEndHour()) {
        return true;
    } else if (currentHour == timerConfiguration.getEndHour()) {
        if (currentMinute > timerConfiguration.getEndMinute()) {
            return true;
        } else if (currentMinute == timerConfiguration.getEndMinute()) {
            if (currentSecond >= timerConfiguration.getEndSecond()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}

private boolean isWorkDay(String selectedDays) {
    if(selectedDays == null){
        LOG.error("selectedDays is NULL!");
        return false;
    }

    LOG.info("selectedDays: " + selectedDays);
    if (selectedDays.equals("?")) {
        return false;
    }

    if (selectedDays.equals("*")) {
        return true;
    }

    Calendar now = GregorianCalendar.getInstance();

    int i = now.get(Calendar.DAY_OF_WEEK);
    LOG.info("now.get(Calendar.DAY_OF_WEEK): " + i);
    if (selectedDays.contains("" + i)) {
        return true;
    } else {
        return false;
    }
}
}  

我要部署这个应用的应用服务器是Weblogic 10.3.4,事务超时配置已调整为30秒。

根据我上面提到的事情,timeout 方法会在开始执行后 30 秒后自动回滚,并且 weblogic 会不断重试。我试图通过注释类、方法来删除此事务,但没有成功。如何使此方法无事务?感谢您的关注。

顺便说一句,balusC 对question 的建议是否足以解决这个问题?

【问题讨论】:

    标签: transactions timer ejb weblogic


    【解决方案1】:

    在这种情况下,使用 BeanManagement 事务。否则,bean Timerservice 本身将启动一个事务以满足使用 XA 接口的默认持久存储(在每种情况下都是 WLS 上的文件存储)上的事务。 此解决方法有助于 Weblogic 应用程序服务器,但也适用于其他应用程序服务器。

    @Stateless 
    
    @Local(TimerBusinessService.class)
    @TransactionManagement(TransactionManagementType.BEAN)
    public class TimerBusinessServiceImpl implements TimerBusinessService {
    
        @Resource
        private TimerService timerService;
    
        @EJB
        private NonTxService nonTxService;
    
        @Override
        public void doStartTimer() throws EjpdBusinessException {
            long everyDay = 86400000;...
            timerService.createTimer(0, everyDay, ...);
        }           
    
        @Timeout
        public void periodicalTimerMethode(Timer timer) throws EjpdBusinessException {
            try {
                nonTxService.proceedAction ();
            } catch (…Exception ex) {
                throw new RuntimeException(“..”, ex);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多