我有一个单独的线程在表中插入行,在每行之后提交。然后,在我的主线程上,我对该表(SELECT COUNT(*)
)进行两次连续读取,两次读取之间的休眠周期为1000 ms。
即使读取应该(?)发生在不同的事务中,这两个读取也会观察到相同的行数。让两个读取返回不同值的唯一方法是在两个读取之间添加commit
(调用方法,breakTransaction
设置为true
)。否则它们似乎在同一事务中执行。
以下代码中使用的ds
类型为org.apache.commons.dbcp.BasicDataSource
:
public void readTwoCounts(boolean breakTransaction) throws SQLException {
Connection conn = ds.getConnection();
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
PreparedStatement ps1 = null;
ResultSet rs1 = null;
PreparedStatement ps2 = null;
ResultSet rs2 = null;
try {
Integer count1 = null;
Integer count2 = null;
{ // 1st READ
ps1 = conn.prepareStatement("SELECT COUNT(*) FROM a");
rs1 = ps1.executeQuery();
rs1.next();
count1 = rs1.getInt("count");
}
if (breakTransaction)
conn.commit();
try {Thread.sleep(1000);} catch (InterruptedException ie) {}
{ // 2nd READ
ps2 = conn.prepareStatement("SELECT COUNT(*) FROM a");
rs2 = ps2.executeQuery();
rs2.next();
count2 = rs2.getInt("count");
}
System.out.printf("%d %d\n", count1, count2);
} finally {
DbUtils.closeQuietly(conn, ps1, rs1);
DbUtils.closeQuietly(conn, ps2, rs2);
}
}
我的问题是:
对Connection
对象的连续读取何时在同一事务上发生,为什么我必须明确调用commit
以确保它们发生在不同的事务中?