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

时间:2015-03-12 05:56:14

标签: hibernate java-ee jboss jobs

目前,我们有一项工作可以将导入文件中的n条记录导入数据库。该课程的结构如下:

@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 -HIBERNATE JBoss的

谢谢, czetsuya

2 个答案:

答案 0 :(得分:0)

您可以考虑使用新的Batch API

答案 1 :(得分:0)

此问题的解决方案是用Tx.NEVER注释主要的工作执行者,然后按实体ID划分和征用记录(或映射减少)。最后,使用注释为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失败,因此我们将错误保存在单元级别以重新执行。