2011-10-22 82 views
1

我有一個EJB Timer 3.0,並且此計時器有一個方法,每次調用大約運行6小時。我已實施該定時器是下面:EJB定時器長時間運行方法和Weblogic 10.3.4問題

@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秒。

在上面提到的事情中,超時方法在執行開始後30秒後自動回滾,並且weblogic不斷重試。我試圖通過註釋類,方法來取消這個事務,但沒有成功。我怎樣才能使這種方法無交易?感謝您的關注。

順便說一下,balusC的推薦是否可以相當於從這個問題中解脫出來的question

回答

1

在這種情況下,請使用BeanManagement Transaction。否則,Bean Timerservice本身將啓動一個事務以滿足使用XA接口的默認持久存儲上的事務(這在任何情況下都是WLS上的文件存儲)。 此替代方法有助於Weblogic Application Server,也可以在其他應用程序服務器上使用。

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