繁体   English   中英

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

[英]How to finish a container-managed transaction before running a long task?

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

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

我的问题是,在prepare并在update之前启动新事务之后,是否有(优雅)的方法来提交和完成事务? 我宁愿使用容器管理的事务,也可能不切换为使用UserTransaction

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

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

有没有办法做到这一点?


经过进一步的测试后,我得出结论:亚历山大的回答是绝对正确的。 我的理解必须改变。 首先,我不知道@Transactional不适用于EJB,而仅适用于CDI bean。 对于EJB,注释称为@TransactionAttribute ,可以将其设置为基本上相同的值。 @Asynchronous@TransactionAttribute(NOT_SUPPORTED)确实有效(如果不等待结果)。

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

  • 使用JMS,发送适当的消息并在MDB中execute (任何版本,但需要完整的概要文件)
  • 使用Java EE 6.0的Timer Service并计划任务以异步执行execute@Timeout
  • 使用Java EE 7.0的批处理API安排适当的长期运行的批处理作业。

后者可能是您要寻找的,但是仅在Java EE 7.0及更高版本中可用。 否则,JMS解决方案是最干净的,但是如果不能选择JMS,则Timer Service应该可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM