1

JDBCを使用して、 PostgresSQL 9.0データベース層を組み込んだ Java プロジェクトに取り組んでいます。SQL は関数にラップされ、JDBC を使用するストアド プロシージャのようにJavaで実行されます。

データベースにはヘッダー詳細スキームが必要であり、詳細レコードにはヘッダーへの外部キー ID が必要です。したがって、ヘッダー行が最初に書き込まれ、次に数千の詳細レコードが書き込まれます。 詳細の書き込みが完了するまで、ユーザーがヘッダーにアクセスできないようにする必要があります。

詳細レコードの書き込みが完了するまでヘッダー レコードをコミットできないように、トランザクション全体をラップすることをお勧めします。ただし、トランザクションを Java の呼び出しに分離したことを以下に示します。ヘッダーを書き込み、詳細をループします (詳細行を書き込みます)。データのサイズが非常に大きいため、詳細なデータを関数に渡して 1 つのトランザクションを実行することは現実的ではありません。

私の質問は、詳細レコードの書き込みが完了するまでヘッダーがコミットされないように、トランザクションを JDBC レベルでラップするにはどうすればよいですか?

最適なソリューションのメタファは、SQL Server の名前付きトランザクションです。このトランザクションは、データ アクセス レイヤー コード (他のトランザクションの外部) で開始され、後の DB 呼び出しで完了することができます。

次の (単純化された) コードはエラーなしで実行されますが、分離の問題は解決されません。

DatabaseManager mgr = DatabaseManager.getInstance();
Connection conn = mgr.getConnection();
CallableStatement proc = null;

conn.setAutoCommit(false);
proc = conn.prepareCall("BEGIN TRANSACTION");
proc.execute();

//Write header details
writeHeader(....);
for(Fault fault : faultList) {
    writeFault(fault, buno, rsmTime, dnld, faultType, verbose);
}
proc = conn.prepareCall("COMMIT TRANSACTION");
proc.execute();

あなたの素晴らしい答えは大歓迎です!

4

2 に答える 2

3

writeHeader と writeFault に同じ接続を使用していますか?

conn.setAutoCommit(false);

headerProc = conn.prepareCall("headerProc...");
headerProc.setString(...);
headerProc.execute();

detailProc = conn.prepareCall("detailProc...");

for(Fault fault : faultList) {
    detailProc.setString(...);
    detailProc.execute();
    detailProc.clearParameters();
}

conn.commit();

そして、その詳細ループの「addBatch」を実際に確認する必要があります。

于 2012-05-01T21:26:20.687 に答える
2

当面の問題は解決したようですが、Java EE コンテナー内で実行している場合は、JTA を調べることをお勧めします。JTA と EJB3.1* を組み合わせると、宣言型のトランザクション制御が可能になり、私の経験ではトランザクション管理が大幅に簡素化されます。

*心配はいりません。EJB3.1 は、以前の EJB 仕様よりもはるかに単純でクリーンで、恐ろしくもありません。

于 2012-05-02T01:35:39.833 に答える