У меня есть 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 секунд.
В свете того, что я упомянул выше, метод тайм-аута автоматически откатывается через 30 секунд после начала выполнения, и weblogic повторяет его непрерывно.Я пытался удалить эту транзакцию, аннотируя класс, метод, но безуспешно.Как я могу сделать этот метод без транзакций?Спасибо за ваш интерес.
Кстати, рекомендация balusC по вопросу значительна для преодоления этой проблемы?