即使自动提交为 false,从连接创建新语句是否会提交所有内容?
Is creating a new statement from a connection commit everything even if auto commit is false?
我有以下代码:
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.jar
与 App.java
.
在同一文件夹中
如果一个连接在事务中执行插入、更新或删除,那么该相同连接的其他语句将能够看到这些更改,即使这些更改尚未被执行已提交,以便 其他连接 可以看到它们。
(其实一般情况下其他连接在commit之前是看不到变化的,但是隔离级别为READ_UNCOMMITTED的事务会在原连接执行commit之前让其他连接看到变化或回滚。)
我有以下代码:
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.jar
与 App.java
.
如果一个连接在事务中执行插入、更新或删除,那么该相同连接的其他语句将能够看到这些更改,即使这些更改尚未被执行已提交,以便 其他连接 可以看到它们。
(其实一般情况下其他连接在commit之前是看不到变化的,但是隔离级别为READ_UNCOMMITTED的事务会在原连接执行commit之前让其他连接看到变化或回滚。)