非常大的数据库插入失败 - MySQL,JPA 2,WildFly 8

时间:2014-10-09 00:12:36

标签: mysql jpa eclipselink wildfly

MySQL社区服务器v5.6.19
JPA 2
的EclipseLink
WildFly 8
Java EE 7
JDK 1.8
容器管理持久性

我尝试从XML文件加载大量参考数据并将其存储在MySQL数据库中。

总共有大约60,000条记录需要写入数据库。

对于前7,500条左右的记录,一切都很好,但后来我得到以下结果: -

    00:06:37,157 WARN  [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012117: TransactionReaper::check timeout for TX 0:ffff0a00000b:2d6361a7:5435c20e:22 in state  RUN
    00:06:37,161 WARN  [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012095: Abort of action id 0:ffff0a00000b:2d6361a7:5435c20e:22 invoked while multiple threads active within it.
    00:06:37,161 WARN  [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012108: CheckedAction::check - atomic action 0:ffff0a00000b:2d6361a7:5435c20e:22 aborting with 1 threads active!

    00:06:37,184 WARN  [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012121: TransactionReaper::doCancellations worker Thread[Transaction Reaper Worker 0,5,main] successfully canceled TX 0:ffff0a00000b:2d6361a7:5435c20e:22
    00:06:37,193 ERROR [org.jboss.as.ejb3] (default task-38) javax.ejb.EJBTransactionRolledbackException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
    00:06:37,193 ERROR [org.jboss.as.ejb3.invocation] (default task-38) JBAS014134: EJB Invocation failed on component MyItemDAO for method public java.lang.Object model.dao.BaseDAO.update(java.lang.Object): javax.ejb.EJBTransactionRolledbackException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)
        at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:163) [wildfly-ejb3-8.1.0.CR2.jar:8.1.0.CR2]
        at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:253) [wildfly-ejb3-8.1.0.CR2.jar:8.1.0.CR2]
        at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:342) [wildfly-ejb3-8.1.0.CR2.jar:8.1.0.CR2]
        at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:239) [wildfly-ejb3-8.1.0.CR2.jar:8.1.0.CR2]
        at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)


然后是更多的警告和错误。所有后续插入语句都失败。

我已经根据ARJUNA错误代码进行了搜索,但我发现的答案似乎表明数据库或表因mysqldump而被锁定。对我来说情况并非如此 - 没有正在进行的mysqldump。

我看到的另一个建议是,MySQL连接的数量可能已经耗尽,但我不确定JPA如何分配连接。我有两个表正在更新,我将合并然后在从源数据文件中完全填充后立即刷新每个实体。

我的数据文件和处理看起来像这样......

    <!-- Reference data file -->
    <!-- Contains 1 x elem_1 record, approx 1000 elem_2 records, and approx 60,000 elem_3 records -->
    <!-- There is a varying number of elem_3 records per elem_2 record -->

    <elem_1 attr1="" attr2="">  <!-- Create detached elem_1 entity -->
    <!-- Persist elem_1 entity and flush elem_1 EM  -->

        <elem_2 attr1="">  <!-- Create detached elem_2 entity -->
            <val_1>Value..</val_1>  <!-- Add value to detached entity  -->
            <val_2>Value..</val_2>  <!-- Add value to detached entity  -->
            <val_3>Value..</val_3>  <!-- Add value to detached entity  -->

            <!-- Persist elem_2 entity and flush elem_2 EM  -->

            <elem_3 attr1="" attr2="" attr3="">  <!-- Create detached elem_3 entity -->
                <child_1>Value..</child_1>  <!-- Add value to detached entity  -->
                <child_2>Value..</child_2>  <!-- Add value to detached entity  -->
                <child_3>Value..</child_3>  <!-- Add value to detached entity  -->
            </elem_3>  <!-- Persist elem_3 entity and flush elem_3 EM -->

            <!-- Repeat above elem_3 process for all elem_3 records -->

            <!-- Call clear() on elem_3 EM -->

        </elem_2>  <!-- Flush elem_2 EM then call clear() on elem_2 EM -->

        <!-- Repeat above elem_2 process for all elem_2 records -->

    </elem_1>

有人可以建议可能造成这种情况的原因吗?更重要的是,如何解决它以便我可以加载所有数据?

2 个答案:

答案 0 :(得分:0)

看起来事务管理器的事务超时,并且您的大量插入超过了超时,因此事务收割器中止长时间运行的事务并且以下插入失败。

可能有一个配置设置可以增加超时,但恕我直言,您最好将大量插入分成较小批量的单独交易。

答案 1 :(得分:0)

事实证明这是由于使用JTA&#39; WildFly JDBC数据源配置中的选项设置为false。

将此设置更改为true后,我能够删除所有虚假的dao.clear()调用,并且查询成功运行。