EJB计时器忽略TransactionTimeout

时间:2016-07-19 13:49:51

标签: java timer jboss ejb-3.0

我在JBoss 6.4上部署了一个EJB计时器。在99%的情况下,计时器工作正常,但有时需要花费一点时间才能完成并抛出PersistenceException: Transaction was rolled back in a different thread!

我发现这是由于transacion超时值太低。我不想编辑默认值,而是覆盖特定于方法的超时。为了解决这个问题,我将功能分为两个方法:一个用@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分钟后仍然超时(默认值)。如何覆盖默认超时以确保计时器完成作业?

1 个答案:

答案 0 :(得分:1)

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

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