为什么这两个连续读取在同一个事务中执行?

时间:2014-01-26 13:43:38

标签: java postgresql jdbc transactions

我有一个单独的线程在表中插入行,在每行之后提交。然后,在我的主线程上,我对该表(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以确保它们发生在不同的事务中?

0 个答案:

没有答案