@Transactional

@Transactionalによりメソッドに注釈を付けると、すべてのデータベースクエリと変更が単一のトランザクションで実行されます。

トランザクションは既定のデータベースを使用し、「スレッドローカルスコープ」に配置され、メソッドが正常に完了するとコミットされます。

@Transactional
public void process(OffsetDateTime startOffset) {
  ...
  customer.save();
  contact.save();
}

Transaction.current()

Transaction.current()を使用すると、既定のデータベースの「スレッドローカルスコープ」から現在のトランザクションが返されます。

@Transactional
public void process(OffsetDateTime startOffset) {
  ...
  Transaction txn = Transaction.current();
  ...
}

database.currentTransaction()を使用すると、通常は既定のデータベースではない、特定のデータベースの現在のトランザクションが返されます。

Database otherDb = DB.byName("other");

Transaction txn = otherDb.currentTransaction();

beginTransaction()

@Transactionalの代わりに、beginTransaction()を使用して明示的なトランザクションを開始できます。トランザクションは「スレッドローカルスコープ」に配置され、それ以降のクエリ、保存、削除などに使用されます。

try with resourcesブロックを使用して、ブロックでエラーが発生した場合にトランザクションが確実に閉じられるようにする必要があります。

try (Transaction transaction = DB.beginTransaction()) {

  // do stuff...
  Customer customer = ...
  customer.save();

  Order order = ...
  order.save();

  transaction.commit();
}

Kotlin transaction.use { }

Kotlin useは、try with resourcesと同様に、トランザクションが閉じられるように使用されます。

DB.beginTransaction().use { transaction ->

  // do stuff...
  val customer = ...
  customer.save();

  val order = ...
  order.save();

  transaction.commit()
}

commit(), rollback(), end()

多くの場合、beginTransaction()の例のように、try with resourcesブロックでtransaction.rollback()transaction.end()を明示的に呼び出す必要はありません。

rollback()はトランザクションをロールバックし、一般にキャッチブロックで使用されます。

end()は、まだコミットされていない場合にトランザクションをロールバックします。主にfinallyブロックでend()を使用します。

Transaction transaction = DB.beginTransaction()
try {
  // do stuff...
  Customer customer = ...
  customer.save();

  Order order = ...
  order.save();

  transaction.commit();

} catch (SomeException e) {
  transaction.rollback();

} finally {
  transaction.end();  // rollback if not committed
}

commitAndContinue()

大規模トランザクションでは、この時点での変更をコミットして処理を継続することが望ましい場合があります。ここでtransaction.commitAndContinue()を使用します。

setRollbackOnly()

transaction.setRollbackOnly()を使用すると、トランザクションはコミットされず、ロールバックのみを実行します。

これは、何らかの「プレビュー」モードで処理を実行し、変更を処理するがコミットしない場合に使用できます。一部のテストシナリオでも役立ちます。

createTransaction()

database.createTransaction()はトランザクションを作成するが、「スレッドローカルスコープ」には配置されません。通常、スレッド間で渡すトランザクションを取得する場合に使用します。

例: トランザクションを開始し、行ロックを取得し、それが成功した場合に、バックグラウンドスレッド経由で実行するためのタスクにトランザクションを渡します。

createTransaction()を使用する場合、クエリや保存などにトランザクションを明示的に使用しなければなりません。明示的にクエリBeanでトランザクションを指定し、...およびmodel.save(transaction)などを指定します。

try (Transaction transaction = DB.getDefault().createTransaction()) {

  ...
  var customer = new QCustomer(transaction) // explicit transaction
    .name.eq("Rob")
    .findOne();
  ...
  customer.update(transaction);  // explicit transaction

}

暗黙のトランザクション

トランザクションが明示的に指定されていない場合、Ebeanはアクションを実行するためのトランザクションを作成します。

クエリ - 読み取り専用トランザクション

クエリーの場合は、Ebean はリードオンリートランザクションを使用しようとします。リードオンリーデータソース が構成されている場合、Ebean はデフォルトでそれを利用しようとします。

挿入、更新、削除

save、insert、update、delete などの永続化リクエストの場合、Ebean はトランザクションを作成し、操作の最後で COMMIT を実行します。