在 javaee 中处理长 运行 作业时超时事务

Timeout transaction when processing long running job in javaee

目前我们有一个作业,将n条记录从一个导入文件导入到数据库中。 class 的结构如下:

@Startup
@Singleton
public class ImportJob implements Job {
    @Inject
    private ImportJobBean importJobBean;

    @Timeout
    public void trigger(Timer timer) {
        importJobBean.execute();
    }
}

@Stateless
public class ImportJobBean {
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void execute() {
        //call other Stateless beans here
    }
}

ImportJob 是调用ImportJobBean 的入口点。我导入10K记录时没有问题,但是当我尝试100K时,我遇到了下面的错误。

12:07:21,986 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost/127.0.0.1:8080-4) javax.resource.ResourceException: IJ000460: Error checking for a transaction
12:07:21,987 ERROR [org.jboss.as.ejb3] (http-localhost/127.0.0.1:8080-4) javax.ejb.EJBTransactionRolledbackException: org.hibernate.exception.GenericJDBCException: Could not open connection

关于执行此功能的最佳方法有何建议?

我的技术栈: -javaee7 -postgresql -休眠 jboss

谢谢, 切苏亚

您可以考虑使用新的 Batch API

我们针对这个问题的解决方案是用 Tx.NEVER 注释主要的作业运行器,然后通过实体 ID 等来划分和征服记录(或 map-reduce)。最后用 Tx.REQUIRES_NEW.

注释的方法创建另一个 SSB

所以基本上是这样的:

SSB (Job Runner), TX.NEVER
-SSB (Job Bean), TX.NEVER
--SSB (Async Bean), @Asynchronous, TX.NEVER
---SSB (Unit Bean), TX.REQUIRES_NEW

然而,这也意味着我们不能完全让 Job 失败,所以我们在单元级别保存错误以供重新执行。