我正在编写一些测试代码,但结果与我的期望不符。
我有一个表,基本上是计数器的行。其他表使用这些行生成应该是唯一的ID。
当我运行下面的代码时,我期望的是第一个到达select语句的线程将锁定该行或表,停止对唯一ID值的所有读取或写入操作。然而,由于第二个线程被休眠了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();
}
synchronized
同步您的方法即可。请注意,这将影响应用程序的性能。 - Luiggi Mendoza