即使自动提交是假的,从连接创建一个新语句提交所有内容?

问题描述 投票:0回答:1

我有以下代码:

import java.sql.*;

class App {
    public static void main(String[] args) {
        HelloJdbc hj = new HelloJdbc();
        hj.insertPerson();
        hj.printPersons();
        hj.close();
    }
}

class HelloJdbc {

    String url = "jdbc:h2:~/persons";
    String username = "username";
    String password = "password";

    // Active connection
    Connection con;

    public HelloJdbc() {
        try {
            Connection con = DriverManager.getConnection(url, username, password); Statement st = con.createStatement();
            // Making sure I have the same data every time
            st.executeUpdate("DELETE FROM person");
            st.executeUpdate("INSERT INTO person VALUES (1, 'Alice');");
            this.con = con;
        } catch (SQLException e) {}
    }

    void insertPerson() {
        try {
            con.setAutoCommit(false);
            con.createStatement().executeUpdate("INSERT INTO person VALUES(2, 'Bob');");
        } catch (SQLException e) {}
    }

    void printPersons() {
        try (Connection con = DriverManager.getConnection(url, username, password);) {
            ResultSet rs = con.createStatement().executeQuery("SELECT * FROM person;");
            while (rs.next()) {
                System.out.println(rs.getObject(1) + " " + rs.getObject(2));
            }
        } catch (SQLException e) {}
    }

    void close() {
        try {
            con.close();
        } catch (Exception e) {}
    }
}

当我运行此代码时,输​​出将是:

1 Alice

我理解,因为在insertPerson我有con.setAutoCommit(false);

但是,当我按如下方式更改printPerson方法时,它使用活动连接而不是新连接:

void printPersons() {
    try {
        ResultSet rs = con.createStatement().executeQuery("SELECT * FROM person;");
        while (rs.next()) {
            System.out.println(rs.getObject(1) + " " + rs.getObject(2));
        }
    } catch (SQLException e) {}
}

输出变为:

1 Alice
2 Bob

我很困惑,从连接创建一个新语句是否提交了先前声明中的所有内容?行为改变的原因是什么?

编译并运行javac App.java; java -cp ".:h2.jar" App;,其中h2.jarApp.java位于同一文件夹中。

sql jdbc transactions commit h2db
1个回答
2
投票

如果连接在事务内执行插入,更新或删除,则该相同连接的其他语句将能够查看更改,即使这些更改尚未提交,以便其他连接可以看到它们。

(实际上,在正常情况下,其他连接在提交之前无法看到更改,但具有READ_UNCOMMITTED隔离级别的事务将允许其他连接在原始连接执行提交或回滚之前查看更改。)

© www.soinside.com 2019 - 2024. All rights reserved.