Java 6 アプリケーション内からデータベースのデッドロックを処理するための優れた戦略を探しています。複数の並列スレッドが同時に同じテーブルに書き込む可能性があります。データベース (Ingres RDMBS) は、デッドロックを検出すると、セッションの 1 つをランダムに強制終了します。
次の要件が与えられた場合、デッドロック状況に対処するための受け入れ可能な手法は何でしょうか?
- 合計経過時間は、合理的に可能な限り短く保つ必要があります
- セッションを強制終了すると、重大な (測定可能な) ロールバックが発生します
- スレッドが
互いに通信する方法がない場合、つまり、戦略は自律的でなければなりません
これまでのところ、私が思いついた戦略は次のようなものです。
short attempts = 0;
boolean success = false;
long delayMs = 0;
Random random = new Random();
do {
try {
//insert loads of records in table 'x'
success = true;
} catch (ConcurrencyFailureException e) {
attempts++;
success = false;
delayMs = 1000*attempts+random.nextInt(1000*attempts);
try {
Thread.sleep(delayMs);
} catch (InterruptedException ie) {
}
}
} while (!success);
何らかの方法で改善できますか?たとえば、一定量 (マジック数) 秒待機します。より良い結果を生み出す別の戦略はありますか?
注:デッドロックが実際には非常にまれであることを確認するために、いくつかのデータベース レベルの手法が使用されます。また、アプリケーションは、同時に同じテーブルに書き込むスレッドをスケジュールすることを回避しようとします。上記の状況は、あくまでも「最悪のシナリオ」になります。
注:レコードが挿入されるテーブルは、ヒープ パーティション テーブルとして編成され、インデックスはありません。各スレッドは、独自のパーティションにレコードを挿入します。