Это реальная простая проблема, я думаю, но я не могу понять, почему так происходит. У меня есть реализация таймера EJB, который использует аннотацию @Singleton, то есть одиночный таймер.Таймер создает несколько экземпляров таймера
Я установил его для запуска через каждые 5 минут. Код выглядит примерно так:
@Singleton
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class Scheduler {
private static final double timerVar = Math.random() * 33;
static Logger logger = Logger.getLogger("Scheduler");
@Schedule(second = "*", minute = "*/5", hour = "*", persistent = true)
public void doWork() {
logger.log(Level.INFO, "timer value for this session : " + timerVar);
}
}
Когда процесс запускает его исполняется 10 экземпляров планировщика одновременно в зазоре 1 сек т.е.
(EJB default - 1)
(EJB default - 2)
(EJB default - 3)
(EJB default - 4)
и так далее. Когда я положил длинную операцию в коде (EJB default - 1)
не является полным и когда (EJB default - 2)
пытается выполнить это дает мне ошибку говоря:
JBAS014373: EJB 3.1 PFD2 4.8.5.5.1 параллельного доступа таймаут на орг. [email protected] - не смог получить замок в 5000 миллисекунды
Во-первых, как я могу избежать нескольких экземпляров EJB планировщика будет выполняться в то время? Во-вторых, что такое сделка с «не удалось получить блокировку в течение 5000MILLISECONDS» и как я могу ее избежать?
Для ошибки таймаута я получаю, я нашел, что в очереди JBOSS много билетов, как указано here.
EDIT
Добавлен код в последнем комментарии, так это читаемым:
@ Tushar-46835, не могли бы вы разъяснить на ваше решение, может показать нам фрагмент того, что ты сделал? - rtcarlson 2 октября '14 в 20:12
@rtcarlson: Вот фрагмент кода, который фиксируется мои вопросы:
@Resource
TimerService timerService;
@Schedule(persistent = false, minute = "/30", hour = "")
public void checkQueueState() {
dt = new DataAccessFactory();
excvo = dt.canExecute();
dt = null;
available = excvo.isExecuteReady();
if (available) {
timerService.createSingleActionTimer(new Date(), new TimerConfig(null, false));
}
}
@Timeout
private void generateReport(Timer timer) {
logger.info("!!--timeout invoked here " + new Date());
}
@ Tushar-46835, можете ли вы рассказать о своем решении, может быть, показать нам фрагмент того, что вы сделали? – rtcarlson
@rtcarlson: Вот фрагмент кода, который исправил мои проблемы: Ресурс TimerService timerService; Расписание (постоянная = ложь, минута = "*/30", час = "*") \t общественного недействительными checkQueueState() { \t \t дт = новый DataAccessFactory(); \t \t excvo = dt.canExecute(); \t \t dt = null; \t \t available = excvo.isExecuteReady(); \t \t если (есть) { \t \t \t timerService.createSingleActionTimer (новая дата(), новый TimerConfig ( \t \t \t \t \t нуль, ложь)); \t \t} \t} \t Timeout \t частный аннулируются generateReport (таймер Timer) { \t \t logger.info ("!! - время ожидания вызова здесь" + новый Date()); \t} – TusharPanda