EJB 计时器忽略 TransactionTimeout

EJB timer ignores TransactionTimeout

我耳边有一个 EJB 计时器,部署在 JBoss 6.4 上。在 99% 的所有情况下,计时器都可以正常工作,但有时它需要太长时间才能完成并抛出 PersistenceException: Transaction was rolled back in a different thread!.

我发现这是由于事务超时值太低造成的。我不想编辑默认值,而是要覆盖特定于方法的超时。为了解决这个问题,我将功能分为两种方法:一种方法用 @Timeout 注释,另一种方法真正起作用。

这是我的计时器实现:

@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 分钟(默认值)后仍然超时。如何覆盖默认超时以确保计时器完成作业?

不确定我是否理解正确。 从您的代码来看,您似乎是从 @Timeout 方法调用 workInNewThread() ,但是有一个带有 Tx 属性的方法 cleanup()。

我猜您是从@Timeout 调用同一个bean 中的方法。 但在这种情况下,@TxAttribute 和 TxTimeout 注释都不会生效,因为容器不控制内部方法调用。 您需要使用不同的 EJB 或自引用来让控制器完成这项工作。 另一种选择是直接注释超时方法。