同一交易中的变更可见性

时间:2018-05-21 14:54:35

标签: jdbc transactions jdbctemplate

我正在setAutoCommit(false)模式下使用JDBC。

在同一个事务中,我执行多个语句进行插入,更新和选择。

问题是:如果这些更改在同一事务中可见,以便后续操作吗?有什么具体规则?它是特定于供应商的吗?它是特定于驱动程序的吗?或者其他什么?

我使用mysql-connector-java 8.0.11,JDBC 4.2,java 8,在我的情况下没有可见的变化,例如。

  try (Connection conn = dataSource.getConnection()) {
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            conn.setAutoCommit(false);
            try (PreparedStatement statement = conn.prepareStatement(sqlInsert, PreparedStatement.RETURN_GENERATED_KEYS)) {
                statement.setString(1, "testData");
                statement.executeUpdate();
                System.out.println("After insertion:");
                // jdbc findAll impl.
                findAll().forEach(System.out::println);
                conn.commit();
            } catch (SQLException ex) {
                conn.rollback();
            }
        } catch (SQLException e) {
            throw new RuntimeException();
        }

此处,插入的未提交数据实际上在同一事务中不可见!

但是,如果我使用Spring的jdbcTemplate和Spring的DataSourceTransactionManager执行相同的操作,请执行以下操作:

final DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();

defaultTransactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
TransactionStatus transaction = txManager.getTransaction(defaultTransactionDefinition);

try {
    // jdbcTemplate insert impl.
    insert("testData");
    System.out.println("After insertion:");
    // jdbcTemplate findAll impl.
    findAll().forEach(System.out::println);
    txManager.commit(transaction);
} catch (Exception e) {
    txManager.rollback(transaction);
}

插入的未提交数据实际上在同一事务中可见!

我在JDBC规范中没有找到任何解释,并且与它混淆。

请解释一下这种行为。

P.S。我知道不同的隔离级别,但它们基本上适用于并发事务,而不是同一个事务。

1 个答案:

答案 0 :(得分:2)

如果评论中的其他信息def replacestring(val): reps = {'Parker':'Borker', '1St':'st', 'Sw':'SW', 'S W':'SW'} for i,j in reps.items(): if i in val: val = val.replace(i,j) return val print(addr_df['ADDRESS1'].apply(replacestring)) 创建了新连接,则问题是您使用一个连接+事务来更新数据,而另一个连接+事务用于选择数据。

选择查询受事务影响:事务确定可见或不可见。您具有事务1的连接1,其中您修改了数据(尚未提交),连接2与事务2执行选择。如果事务1尚未提交,则事务2无法查看事务1更改的数据。

如果使用findAll和Spring事务管理器,事情会发生变化,因为Spring会做更多的工作来确保它为更新和选择使用相同的连接和事务。