Jdbc 同一事务中更改的可见性

Jdbc 同一事务中更改的可见性,jdbc,transactions,jdbctemplate,Jdbc,Transactions,Jdbctemplate,我在setAutoCommit(false)模式下使用JDBC 在同一事务中,我执行多条insert、update和select语句 问题是:对于后续操作,这些更改是否应该在同一事务中可见?有什么具体规定?它是特定于供应商的吗?它是特定于驱动程序的吗?或者别的什么 我使用mysql连接器java 8.0.11、JDBC 4.2、java 8,在我的例子中,没有可见的更改,例如 try (Connection conn = dataSource.getConnection()) {

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

在同一事务中,我执行多条insert、update和select语句

问题是:对于后续操作,这些更改是否应该在同一事务中可见?有什么具体规定?它是特定于供应商的吗?它是特定于驱动程序的吗?或者别的什么

我使用mysql连接器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规范中找不到任何解释,对此感到困惑

请解释一下这种行为


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

在您的评论中有附加信息,即
findAll
创建了一个新连接,问题是您正在使用一个连接+事务来更新数据,和另一个连接+事务来选择数据

select查询受事务影响:事务确定哪些内容可见或不可见。您拥有与事务1的连接1,其中您修改了数据(尚未提交),以及与执行选择的事务2的连接2。给定事务1尚未提交,事务2无法看到事务1更改的数据


如果您使用
JdbcTemplate
和Spring事务管理器,情况会发生变化,因为Spring会做额外的工作,以确保它在更新和选择时使用相同的连接和事务。

请发布一篇文章。您当前正在隐藏详细信息。例如:那
findall()
方法做什么?我猜它将创建一个新的连接,并因此拥有自己的事务。没错,这就是重点。我在findAll()方法中创建了一个新连接。如果我在给定连接中实现所有逻辑findAll(),那么所有数据都是可见的。没想到,select查询会影响当前事务。