2016-07-19 4 views
0

У меня есть таймер EJB в ухе, развернутый на JBoss 6.4. В 99% случаев таймер работает нормально, но иногда требуется слишком много времени для завершения и выбрасывает PersistenceException: Transaction was rolled back in a different thread!.Таймер EJB игнорирует TransactionTimeout

Я обнаружил, что это связано с слишком низким значением тайм-аута транзакции. Я не хочу изменять значение по умолчанию, а скорее переопределять тайм-аут, зависящий от метода. Чтобы решить эту проблему, я разделил функциональность на два метода: один метод, аннотированный с помощью @Timeout, и тот, который фактически выполняет эту работу.

Вот мой таймер implememntation:

@Singleton 
public class MyTimer implements SomeTimerInterface { 

    @EJB 
    private SomeManager myManager; 

    @Resource 
    private TimerService timerService; 

    private Timer timer; 

    @Override 
    public void startTimer() { 

     // Timer scheduled to fire every 7th minute 
     ScheduleExpression schedule = new ScheduleExpression(); 
     schedule = schedule.hour("*").minute("*/7").second("00"); 

     TimerConfig config = new TimerConfig(); 
     config.setPersistent(false); 

     timer = timerService.createCalendarTimer(schedule, config); 
    } 

    @Timeout 
    @AccessTimeout(value = 20, unit = TimeUnit.MINUTES) 
    public void handleTimeout() { 

     workInNewThread(); 
    } 

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    @TransactionTimeout(unit = TimeUnit.SECONDS, value = 900) 
    public void workInNewThread() { 

     // This can take anything from 1 sec to 15 min. 
     List<Object> objects = myManager.getAllTheDatabaseObjects(); 
    } 
} 

Однако, таймер кажется игнорировать TransactionTimeout, как его еще раз через 5 минут (значение по умолчанию). Как я могу переопределить тайм-аут по умолчанию, чтобы убедиться, что таймер заканчивает работу?

ответ

1

Не уверен, правильно ли я понял. Из вашего кода это выглядит так, как вы вызываете workInNewThread() из вашего метода @Timeout, но есть метод cleanup() с атрибутом Tx.

Я предполагаю, что вы вызываете методы в одном и том же компоненте из вашего @Timeout. Но в этом случае аннотации, а не @TxAttribute или TxTimeout, вступят в силу, поскольку контейнер не контролирует вызов внутреннего метода. Вам нужно использовать другой EJB или собственную ссылку, чтобы позволить контроллеру выполнить эту работу. Другой вариант - аннотировать метод тайм-аута напрямую.

+0

К сожалению, я переименовал метод для ясности, когда я написал пример. cleanup и workInNewThread - это те же методы. Я редактировал мой пост сейчас. – Pphoenix

+0

, поэтому мне нужно получить прокси для моего класса и вызвать метод на этом объекте? Я нашел что-то похожее в этой теме, https://developer.jboss.org/thread/165400?tstart=0 – Pphoenix

+0

Я только что протестировал это, работал безупречно. Используется другой EJB для разделения проблем между управлением таймером и бизнес-логикой. – Pphoenix

Смежные вопросы