如何在运行长任务之前完成容器管理的事务?

时间:2015-07-14 13:50:01

标签: java transactions ejb java-ee-7

我的任务包括3个步骤prepareexecuteupdateprepareupdate需要在交易中工作,而execute需要很长时间(即几分钟到几小时)。该任务是EJB的一部分,即:

@Stateless
public class Task {
    public void doTask() {
        prepare();
        execute();
        update();
    }
}

我的问题是,是否有一种(优雅)方式在prepare之后提交并完成交易并在update之前开始新的交易?我宁愿使用容器管理的事务,也可能不会切换到使用UserTransaction

如果获得任何优势,可以将任务拆分为单个EJB,但请注意暂停execute的事务(即使用@Transactional(TxType.NOT_SUPPORTED)是不够的,因为这仍然会触发超时。< / p>

我尝试将其拆分为TaskExecute类,其中包含@Asynchronous @Transactional(NOT_SUPPORTED) public void execute()并在完成后发送事件。但这似乎也不起作用。

有办法做到这一点吗?

经过一些进一步的测试后,让我得出结论:Alexanders的回复是绝对正确的。我的理解必须改变。最重要的是,我不知道@Transactional不适用于EJB,而只适用于CDI bean。对于EJB,注释称为@TransactionAttribute,可以设置为基本相同的值。 @Asynchronous@TransactionAttribute(NOT_SUPPORTED)的组合确实有效(如果不等待结果)。

1 个答案:

答案 0 :(得分:1)

这取决于您要使用的Java EE版本。以下是三种可能的解决方案。

  • 使用JMS,发送相应的消息并在MDB中执行execute(任何版本,但需要完整的配置文件)
  • 使用Java EE 6.0的定时服务并安排任务以异步方式执行execute@Timeout
  • 使用Java EE 7.0的批处理API来安排正确的长时间运行批处理作业。

后者可能正是您所寻找的,但仅适用于Java EE 7.0及更高版本。否则,JMS解决方案是最干净的,但如果JMS不是一个选项,定时服务应该可以工作。