期待した結果が得られないスパイク コードを書いています。
基本的にカウンターの行であるテーブルがあります。他のテーブルはこれらの行を使用して、一意の ID を生成します。以下のコードを実行すると、select ステートメントに到達する最初のスレッドがその行またはテーブルのロックを取得し、一意の ID 値に対するすべての読み取りまたは書き込みが停止することを除いて例外がありました。ただし、2 番目のスレッドは常に最初のスレッドよりも前に完了します。これは、1 秒間スリープ状態になっているためです。したがって、両方とも同じ値を読み取り、同じ値を書き込むため、例外として 2 回ではなく 1 回だけインクリメントされます。
私のコードに何か問題がありますか、それとも分離レベルの理解が間違っていますか?
ボイラープレートコードを削除しました。MySQL データベースを使用した標準の sql.Connection。
private void incrementValue() {
connection
.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
statement = connection.createStatement();
System.out.println(Thread.currentThread().getName()
+ " doing select");
resultSet = statement.executeQuery("select * from counter");
System.out.println(Thread.currentThread().getName()
+ "after select");
if (counter++ == 0) {
Thread.sleep(1000);
}
String incrementedValue = getIncrementedValue(resultSet);
statement.executeUpdate("update counter set counter='"
+ incrementedValue + "'");
}
private String getIncrementedValue(ResultSet resultSet) throws SQLException {
String value = "";
if (resultSet.next()) {
System.out.println(Thread.currentThread().getName() + "Value was "
+ resultSet.getString(1));
value = (new Integer(resultSet.getString(1)) + 1) + "";
}
return value;
}
これはメインから呼び出されます
public static void main(String[] args) {
DatabaseExample databaseExample = new DatabaseExample();
Runnable runnable = new Runnable() {
@Override
public void run() {
DatabaseExample databaseExample = new DatabaseExample();
databaseExample.incrementValue();
}
};
new Thread(runnable).start();
databaseExample.incrementValue();
}