I have the following code:
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) {}
}
}
When I run this code, the output will be:
1 Alice
This I understand, since in insertPerson
I have con.setAutoCommit(false);
However, when I change the printPerson
method as follows, so that instead of a new connection, it uses the active connection:
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) {}
}
The output changes to:
1 Alice
2 Bob
I am confused, does creating a new statement from a connection commits everything from a prior statement? What is the cause of the behavior change?
Compile & run with javac App.java; java -cp ".:h2.jar" App;
where you have h2.jar
in the same folder with App.java
.
If a connection performs an insert, update, or delete inside a transaction then other statements of that same connection will be able to see the changes even if those changes have not been committed so that other connections can see them.
(Actually, under normal circumstances other connections cannot see the changes until they are committed, but a transaction with the isolation level of READ_UNCOMMITTED will allow other connections to see the changes before the original connection performs a commit or a rollback.)