2

autocommit = trueでJDBCを使用しています。操作の 1 つで、準備済みステートメントを使用してバッチ挿入を行っています。

public void executeBatchInsert(String query, List<Object[]> entityList)  {
        try {
            pstmt = conn.prepareStatement(query);
            for(int i=0; i<entityList.size(); i++) {
                int j=1;
                for(Object o: entityList.get(i)) {
                    pstmt.setObject(j++, formatColumnValue(o));
                }

                pstmt.addBatch();
                if((i+1)%1000 == 0) {
                    pstmt.executeBatch();
                }
            }
            pstmt.executeBatch();
        } catch (SQLException e) {
        }
    }

実行中に例外が発生した場合、この接続を閉じると、すべてのロックが解除され、ロールバックが発生しますか?

-- B.テジャ。

4

3 に答える 3

5

あなたの質問に対する直接的な答えは、いいえです。例外が発生した場合は、rollbackメソッドを手動で呼び出す必要があります。そして、そうする前に、する必要setAutoCommitがありfalseます。デフォルトでは、自動コミットは に設定されていtrueます。自動コミットが に設定されていると、をtrue実行できません。そのことを知らせる が発生します。rollbackexception

autoCommit後で元に戻すことを忘れないでください。そうしないtrueと、他の方法で予期しない結果が生じる可能性があります。

この機能を実装する方法の例を次に示します。これは単なるスケッチであり、connectionprepared statment、などの処理方法にもっと注意を払う必要がありますexception

public void insertAndRollback(Connection connection) {
    try {
        final ArrayList parameters = new ArrayList();

        // Add your parameters to the arraylist
        parameters.add("John");
        parameters.add("Lee");
        parameters.add("Mary");
        parameters.add("Peter");
        parameters.add("Lewis");
        parameters.add("Patrick");

        final String parameterizedQuery = "insert into person (name) values (?)";

        final int batchSize = 5; // Set your batch size here
        int count = 0;
        int aux = 0;

        // Get the total number of '?' in the query
        int totalQueryParameters = Utils.countCharOccurrences(parameterizedQuery, '?');
        final int auxTotalQueryParameters = totalQueryParameters;

        final PreparedStatement preparedStatement = connection.prepareStatement(parameterizedQuery);

        // Auto Commit must be set to false
        connection.setAutoCommit(false);

        for(int i = 0; i < parameters.size(); i++)
        {
            Object obj = parameters.get(i);

            aux++;
            preparedStatement.setObject(aux, obj);

            if(totalQueryParameters == i + 1) { // Because the ArrayList starts from zero.
                // First query "parsed" - > Add to batch
                preparedStatement.addBatch();
                // One query has been added to the batch. Re-adapt the cycle.
                totalQueryParameters = totalQueryParameters + auxTotalQueryParameters;
                aux = 0;
            }

            if(++count % batchSize == 0) {
                preparedStatement.executeBatch();
            }
        }

        preparedStatement.executeBatch(); // insert remaining queries
        preparedStatement.close();
        connection.setAutoCommit(true); // Make it back to default.
    } catch (SQLException ex) {
        // Do the rollback
        doRollback(connection);

        try {
            // Make it back to default.
            connection.setAutoCommit(true);
        } catch (SQLException ex1) {
            ex1.printStackTrace();
        }

        // Dont forget to close the preparedStatement and the connection
        // if you don't need the connection open any more.

        ex.printStackTrace();
    }
}


private void doRollback(Connection c) {
    try {
        c.rollback();
    } catch (SQLException ex) {
        ex.printStackTrace();
    }
}
于 2014-10-11T01:48:42.723 に答える
1

autocommit=true注意が必要です。バッチを実行するときは、 強くお勧めしません。

getUpdateCount()そうは言っても、残りを実行するためにロジックを使用して構築することをお勧めします。

最後にcommit

于 2013-01-31T12:11:56.260 に答える