保存点
Ebean 支持使用 Savepoints
,这是大多数关系数据库的一个功能,我们可以在事务中创建保存点(嵌套事务),该事务可以作为工作单元提交或回滚。
如果我们有一个执行某些操作的任务,这些操作可能会失败/回滚,但不想丢失整个事务的所有工作,Savepoint
提供了一种执行此操作的机制。您可以在 Oracle 的 JDBC 教程 中查看更多信息
Transaction.setNestedUseSavepoint()
对于事务,我们可以使用 transaction.setNestedUseSavepoint()
启用它以使用 Savepoint
进行嵌套事务。这意味着这些嵌套事务可以回滚,而外部事务可以继续进行并可能提交。
示例
// start 'outer' transaction
try (Transaction outerTxn = database.beginTransaction()) {
outerTxn.setNestedUseSavepoint();
// do stuff with the 'outer' transaction
bean.save();
try (Transaction nestedTransaction = database.beginTransaction()) {
// nested transaction is a savepoint ...
// do some piece of work which we might want to either commit or rollback ...
otherBean.save();
if (...) {
nestedTransaction.rollback();
} else {
nestedTransaction.commit();
}
}
// continue using 'outer' transaction ...
outerTxn.commit();
}
显式保存点
作为使用 transaction.setNestedUseSavepoint() 的替代方法,我们可以通过从事务中获取 JDBC Connection
来显式创建和使用保存点。
例如
var newCustomer = new Customer();
newCustomer.setName("John");
newCustomer.save();
try (Transaction transaction = DB.beginTransaction()) {
Connection connection = transaction.getConnection();
// create a Savepoint
Savepoint savepoint = connection.setSavepoint();
newCustomer.setName("Doe");
newCustomer.save();
// Rollback to a specific save point
connection.rollback(savepoint);
transaction.commit();
}
var found = DB.find(Customer.class, newCustomer.getId());
System.out.println(found.getName()); // Prints "John"