java - H2事务总是自动提交为什么?
问题描述
我的应用程序只有 java 和 maven(没有其他框架)
在 pom.xml 中,我依赖于 H2 数据库:
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
</dependencies>
我以这种方式创建了一个连接,您可以看到我将 autocommit 设置为 false。我的 H2 数据库在内存中。
public class ConnectionManager {
public static Connection getConnectionManager() throws SQLException {
Properties myProp = new Properties();
myProp.put("user" , "sa");
myProp.put("password", "");
myProp.put("autocommit", "false");
return DriverManager.getConnection("jdbc:h2:mem:test", myProp);
}
public static void closeConnection(Connection connection) throws SQLException {
connection.close();
}
}
我创建了示例表:
public class InitDatabaseManager {
private static final String CREATE_TABLE_SQL =
"CREATE TABLE IF NOT EXISTS users ("
+ "ID INT NOT NULL AUTO_INCREMENT,"
+ "EMAIL VARCHAR(45) NOT NULL,"
+ "PRIMARY KEY (ID))";
private static final String DROP_TABLE_USERS = "drop table if exists users;";
public static void initStarterTable (Connection connection) throws SQLException {
Statement stmt = connection.createStatement();
stmt.executeUpdate(DROP_TABLE_USERS);
stmt.executeUpdate(CREATE_TABLE_SQL);
}
}
我的问题是为什么在下面的代码中我插入到 H2 数据库的记录虽然我禁用了自动提交?
public static void insertUsers(Connection connection) throws SQLException {
connection.setAutoCommit(false);
System.out.println("[INSERT]");
String sqlInsert1 = "INSERT INTO users (email) VALUES ('user@mail.com');";
PreparedStatement psInsert = connection.prepareStatement(sqlInsert1);
System.out.println(connection.getAutoCommit());
psInsert.execute();
psInsert.close();
}
解决方案
我添加了两个连接,然后更改了隔离级别,我的问题是为什么第二个事务看不到第一个事务所做的更改。第一个事务不提交更改,因此如果事务隔离级别为 TRANSACTION_READ_UNCOMMITTED,则第二个事务应该看到第一个事务的更改。
我知道:
H2 只支持三个隔离级别;读取未提交,读取已提交和可序列化,只能在连接级别(不是每个事务)设置。默认为已提交读。
public class StartUseCases {
private static Connection connection;
private static Connection connection2;
public StartUseCases() {
try {
connection = ConnectionManager.getConnectionManager();
connection.setAutoCommit(false);
connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
connection2 = ConnectionManager.getConnectionManager();
connection2.setAutoCommit(false);
connection2.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
InitDatabaseManager.initStarterTable(connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws SQLException {
// init tables
new StartUseCases();
CRUD.getAllUsers(connection);
CRUD.insertUsers(connection2);
CRUD.getAllUsers(connection);
}
}