[英]H2 transactions always automatically commit why?
我的應用程序只有 java 和 maven (沒有其他框架)
在 pom.xml 中,我依賴於 H2 數據庫:
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
</dependencies>
我以這種方式創建了一個連接,您可以看到我將 autocommit 設置為 false。 我的 H2 數據庫位於 memory 中。
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();
}
當您執行INSERT
命令時,它會將指定的行插入到表中。 此行僅對執行此操作的事務可見,而對其他事務不可見(如果它們使用默認的“已提交”隔離級別)。 在隱式(由於自動提交)或顯式手動提交之后,插入的行對所有事務都是可見的。 如果您回滾事務而不是提交,則該行將消失。
其他數據修改操作以相同的方式工作。 未提交的更改僅對執行它們的事務可見,已提交的更改對所有人可見。
事務有不同的隔離級別,但是 H2 的默認存儲引擎在 1.4.199 中還不支持它們(這種支持將在 1.4.200 中包含)。
每個 JDBC 連接都有自己的 session 並且這個 session 有自己的事務。 我猜你使用相同的連接來讀取插入的數據,因此它可以看到未提交的行。 如果您不想看到它們,請使用其他連接。
H2 中的數據定義命令(如CREATE TABLE
)通常會導致隱式提交,詳見 H2 的文檔。
我添加了兩個連接,然后更改了隔離級別,我的問題是為什么第二個事務看不到第一個事務所做的更改。 第一個事務不提交更改,因此如果事務隔離級別為 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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.