0

このチュートリアルを読みました: http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.htmlしかし、まだ何かが足りないと思います。

例を見てみましょう:

  • スレッド T1 には独自の接続があります
  • スレッド T2 には独自の接続があります

したがって、これらのスレッドはトランザクションを実行します (2 つの異なる接続で setAutoCommit(false))。このトランザクションは、単一の DB テーブルで次のクエリを実行します。

  • 行を選択して累進番号 (PN) を読み取ります
  • プログレッシブ番号を次のように設定する行を挿入します: PN++ (私が
    読んだもの +1)

プログレッシブ番号は、このテーブルで一意である必要があります (主キーです)。

JDBC トランザクション (TRANSACTION_READ_COMMITTED 分離レベルを使用) は、T1 と T2 が同じ PN の値を読み取り、両方が同じ PN++ をテーブルに挿入しようとする問題を回避しますか? 挿入が実行され、commit() が呼び出されるまで、テーブルはロックされていますか?

4

2 に答える 2

1

いいえ、常に一意の番号を使用できるようにするには、次のことを行う必要があります。1)[より良い] DBフィールドをDBに応じてID/シーケンス/自動番号に変更する2)識別子としてUUIDを使用する3)[最悪の]ロック読み取り/インクリメント/書き込みシーケンスの期間の行

TRANSACTION_READ_COMMITTEDは、DBにすでにコミットされているデータのみを読み取ることができることのみを確認します。つまり、間にさらに200のDB操作があった場合

UPDATE sequence 

commit

他のスレッドは、コミットするまで更新したデータを読み取ることができないため、実際には、必要なものとはまったく逆の動作をします。

于 2012-07-19T11:35:25.563 に答える
0

アプリケーション レベルで同期することもできます。これは、1 つのアプリケーションで 1 つのメソッドだけがインクリメントを実行している場合に機能します。

private **synchronized** void increment() {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int current = dao.getMaxNumber(year);
    dao.insertNumber(year, current+1);
}
于 2013-09-04T08:05:07.333 に答える