Java 为什么在同一事务中执行这两次连续读取?
我有一个单独的线程在表中插入行,在每行之后提交。然后,在我的主线程上,我对该表执行两次连续读取,选择COUNT*,两次读取之间的睡眠时间为1000毫秒 两次读取观察到的行数相同,即使读取应该发生在不同的事务中。让两次读取返回不同值的唯一方法是在两次读取之间添加一个commit,并调用将breakTransaction设置为true的方法。否则,它们似乎在同一事务中执行 下面代码中使用的ds类型为org.apache.commons.dbcp.BasicDataSource: 我的问题是:Java 为什么在同一事务中执行这两次连续读取?,java,postgresql,jdbc,transactions,Java,Postgresql,Jdbc,Transactions,我有一个单独的线程在表中插入行,在每行之后提交。然后,在我的主线程上,我对该表执行两次连续读取,选择COUNT*,两次读取之间的睡眠时间为1000毫秒 两次读取观察到的行数相同,即使读取应该发生在不同的事务中。让两次读取返回不同值的唯一方法是在两次读取之间添加一个commit,并调用将breakTransaction设置为true的方法。否则,它们似乎在同一事务中执行 下面代码中使用的ds类型为org.apache.commons.dbcp.BasicDataSource: 我的问题是: 连接对
连接对象上的连续读取何时发生在同一事务上?为什么我必须显式调用commit以确保它们发生在不同的事务中?您使用的是哪种DBMS?博士后?Oracle?好吧,这就是事务的工作方式:当您没有提交或回滚时,您将保持在同一个事务中。否则,每个DB操作都会定义自己的事务,这是autocommit所做的,也是您在一个严肃的应用程序中通常不希望看到的,因为您希望多个操作是原子的、一致的,并且与其他操作隔离。@JBNizet OK,只要我将autocommit设置为false,我不需要显式提交连接对象上的任何内容,同一连接对象上的所有读取都将在同一事务上。对吗?@a_horse_,没有名字,PostgreSQLRight。您总是在事务中,调用commit会提交事务。
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);
}
}