セーブポイント

Ebeanは、トランザクション内で作業単位としてコミットまたはロールバックできるセーブポイント(ネストされたトランザクション)を作成可能な、ほとんどのリレーショナルデータベースの機能であるSavepointsの使用をサポートしています。

失敗またはロールバックする可能性のある操作を実行するタスクがあり、トランザクション全体の作業を失いたくない場合は、セーブポイントはこのメカニズムを提供します。詳細については、オラクルの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"