使用保存点
保存点提供了回滚部分事务的机制。 在 SQL Server 中,可以使用 SAVE TRANSACTION savepoint_name 语句创建保存点。 然后,运行 ROLLBACK TRANSACTION savepoint_name 语句回滚到保存点,而不是回滚到事务的开始。
保存点在不可能发生错误的情况下很有用。 在不频繁发生错误的情况下使用保存点回滚部分事务,其效果好于在执行更新前测试各事务以查看更新是否有效。 更新和回滚都是耗费大量资源的操作,因此,仅当遇到错误的可能性很低,且预先检查更新有效性的成本相对较高时,保存点才会有效。
Microsoft JDBC Driver for SQL Server 支持通过 SQLServerConnection 类的 setSavepoint 方法来使用保存点。 通过使用 setSavepoint 方法,可以在当前事务中创建命名或未命名的保存点,并且该方法将返回 SQLServerSavepoint 对象。 一个事务中可创建多个保存点。 要将事务回滚到指定的保存点,可以将 SQLServerSavepoint 对象传递给 rollback (java.sql.Savepoint) 方法。
下面的实例中,将在执行 try
块中包含两个独立语句的本地事务时使用保存点。 该语句将根据 AdventureWorks2022 示例数据库中的表 Production.ScrapReason 来运行,并使用保存点回滚第二个语句。 这会导致只有第一个语句提交给数据库。
public static void executeTransaction(Connection con) {
try(Statement stmt = con.createStatement();) {
con.setAutoCommit(false);
stmt.executeUpdate("INSERT INTO Production.ScrapReason(Name) VALUES('Correct width')");
Savepoint save = con.setSavepoint();
stmt.executeUpdate("INSERT INTO Production.ScrapReason(Name) VALUES('Wrong width')");
con.rollback(save);
con.commit();
System.out.println("Transaction succeeded.");
}
catch (SQLException ex) {
ex.printStackTrace();
try {
System.out.println("Transaction failed.");
con.rollback();
}
catch (SQLException se) {
se.printStackTrace();
}
}
}