我正在寫一些尖峯代碼,它不會給我我期待的結果。java.sql.Connection隔離級別
我有一個表,基本上是行的計數器。其他表使用這些行來生成應該是唯一ID的內容。 當我運行下面的代碼時,我所看到的是第一個到達select語句的線程將獲得該行或表的鎖,停止對唯一id值的所有讀或寫操作。然而第二個線程總是在第一個線程之前完成,因爲它已經睡了1秒,因此它們都讀取相同的值並寫入相同的值,所以它只增量一次,而不是我除外的兩倍。
我的代碼有什麼問題,或者是我對隔離級別的理解不正確?
我已經刪除了鍋爐板代碼。標準的sql.Connection使用MySQL數據庫。
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();
}
在這種情況下,必須在級別應用程序中進行鎖定。只需使用關鍵字'synchronized'同步你的方法。請注意,這會影響應用程序的性能。 – 2013-02-09 15:00:13