0

OracleデータベースとJDBCでEJB3を使用しています。

私は 25000 のUPDATEクエリを起動する必要があるアプリに取り組んでいます。

私のコードは次のとおりです。

public int updateStatus(List<String> idList) {
    Connection connection = getConnection(); // Connection initialized properly for oracle db
    statement = connection.createStatement();
    String sql = null;
    for (String id : idlist) { // idList is properly filled
        sql = "UPDATE TBLTEST SET STATUS = 'FIXED' WHERE ID = '" + id + "'";
        statement.addBatch(sql);
    }
    int[] affectedRecords = statement.executeBatch();
}

このメソッドが記述されているクラスには、次のように注釈が付けられていることに注意してください。

@TransactionManagement(TransactionManagementType.CONTAINER)

このコードは、8000 クエリまで問題なく動作します。それ以上idの s の場合、次の例外がスローされます。

org.jboss.util.NestedSQLException: Transaction TransactionImple < ac, BasicAction: 0:ffffc0a80272:1652:56bd6be5:57e status: ActionStatus.ABORTED > cannot proceed STATUS_ROLLEDBACK; - nested throwable: (javax.transaction.RollbackException: Transaction TransactionImple < ac, BasicAction: 0:ffffc0a80272:1652:56bd6be5:57e status: ActionStatus.ABORTED > cannot proceed STATUS_ROLLEDBACK)
    at org.jboss.resource.adapter.jdbc.WrapperDataSource.checkTransactionActive(WrapperDataSource.java:165)
    at org.jboss.resource.adapter.jdbc.WrappedConnection.checkTransactionActive(WrappedConnection.java:843)
    at org.jboss.resource.adapter.jdbc.WrappedConnection.checkStatus(WrappedConnection.java:858)
    at org.jboss.resource.adapter.jdbc.WrappedConnection.checkTransaction(WrappedConnection.java:835)
    at org.jboss.resource.adapter.jdbc.WrappedConnection.createStatement(WrappedConnection.java:183)

誰でも例外を手伝ってもらえますか?

4

1 に答える 1

1

最良の推測: 代わりに個々の SQL ステートメントを使用しPreparedStatementて、ドライバーにすべてのステートメント (400k を超える文字データ) を強制的に DB に送信させ、DB がその 400k 文字すべてを解析して、ある時点で制限に達し、問題が発生するようにします。 (例外は、原因となった例外を隠しているため、どこで何が壊れたのか明確ではありません)。

直し方:

一度に「多すぎない」ステートメントの個々のバッチに移動します-たとえば... 1000:

public int updateStatus(List<String> idList) {
    List<Integer> affectedRecords = new ArrayList<Integer>(idList.size());
    try(Connection connection = getConnection(); 
        Statement statement = connection.createStatement()) {
        int count = 0;
        for (String id : idList) {          
            statement.addBatch("UPDATE TBLTEST SET STATUS = 'FIXED' WHERE ID = '" + id + "'");
            //Execute after 1000 rows 
            if(++count % 1000 == 0) {
                int[] result = statement.executeBatch();
                //Utility Method - you need to implement to add int[] into the List
                addResults(affectedRecords, result);
                statement.clearBatch();             
            }
        }
        //In need of final execute?
        if(count % 1000 > 0) {
          // For good measure execute once more
          int[] result = statement.executeBatch();
          //Utility Method - you need to implement to add int[] into the List
          addResults(affectedRecords, result);      
        }              
    } catch(SQLException se) {
        se.printStackTrace();
    }
}
于 2016-02-12T09:15:41.333 に答える