バッチ

JDBCバッチの使用は、transaction.setBatchMode(true) を使用して明示的に有効にすることができます。

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

  // use JDBC batch
  transaction.setBatchMode(true);

  // these go to batch buffer
  aBean.save();
  bBean.save();
  cBean.save();

  // batched
  database.saveAll(someBeans);

  // flush batch and commit
  transaction.commit();
}

@Transactional(batchSize)

@Transactional を使用する場合、batchSize 属性を設定するとJDBCバッチが有効になります。

@Transactional(batchSize = 50)
public void doGoodStuff() {

  ...
}

バッチサイズ

バッチサイズは、EbeanがJDBCプリペアドステートメントをバインドしてから実行する回数を制御します。Beanの永続化(例:customer.save())では、事実上、永続化されるBeanの数になります。

Bean(またはSqlUpdateまたはCallableSql)の数がバッチサイズに達すると、バッチはフラッシュされ、バッファー内のすべてのステートメントが実行されます。

"order"と"order details"など、異なるタイプのBeanを永続化する場合は、いずれかのバッファーがバッチサイズに達すると、すべてバッファーがフラッシュされます。これにより、Ebeanは実行順序を維持できます(例:「order」をすべて永続化してから「order details」をすべて永続化)。

バッチバッファーサイズのデフォルト値は、databaseConfig.persistBatchSize で設定され、デフォルトは20です。バッファーサイズは、transaction.setBatchSize()または@Transactional(batchSize)を使用してトランザクションで設定できます。

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

  // use JDBC batch
  transaction.setBatchMode(true);
  transaction.setBatchSize(50);

  // these go to batch buffer
  aBean.save();
  ...

  // flush batch and commit
  transaction.commit();
}

GetGeneratedKeys

デフォルトでは、EbeanはBeanが挿入された後に生成されたキーを取得します。大量の行/Beanを挿入する処理があり、挿入後にキーが実際には必要ない場合は、パフォーマンス上の利点を得るために生成されたキーの取得をオフにすることができます。

// don't bother getting back the generated keys
transaction.setGetGeneratedKeys(false);

大量のバルク挿入を実行する場合、getGeneratedKeysをオフにするのが一般的です。

try (Transaction transaction = database.beginTransaction()) {
  transaction.setBatchMode(true);
  transaction.setBatchSize(100);

  // turn off GetGeneratedKeys as we don't need the keys
  transaction.setGetGeneratedKeys(false);

  // maybe even turn off persist cascade ...
  transaction.setPersistCascade(false)

  // perform lots of inserts ...
  ...


  transaction.commit();
}

フラッシュ

バッチは、次の場合にフラッシュされます。

  • バッファーがバッチサイズに達した場合
  • クエリを実行した場合 - setFlushOnQuery()による
  • SqlUpdate、CallableSqlとBeanの永続化を混在させた場合 - setFlushOnMixed()による
  • 既にバッチ処理されているBeanのプロパティのゲッターまたはセッターを呼び出した場合(例:bean.getId())
  • 明示的にflush()を呼び出した場合

setFlushOnQuery()

クエリを実行してもフラッシュしたくない場合は、トランザクションでsetFlushOnQuery(false)を設定します。

try (Transaction transaction = database.beginTransaction()) {
  transaction.setBatchMode(true);
  transaction.setFlushOnQuery(false);

  // these go to batch buffer
  aBean.save();
  ...

  // execute this query but we don't
  // want that to trigger flush
  SomeOtherBean.find.byId(42);

  ...

  transaction.commit();
}

setFlushOnMixed()

SqlUpdateまたはCallableSqlとBeanのsave()、delete()などを混在させて実行してもフラッシュしたくない場合は、トランザクションでsetFlushOnMixed(false)を設定します。

try (Transaction transaction = database.beginTransaction()) {
  transaction.setBatchMode(true);
  transaction.setFlushOnMixed(false);

  // these go to batch buffer
  aBean.save();
  ...

  // execute SqlUpdate but we don't
  // want that to trigger flush
  SqlUpdate update = ...
  update.execute();

  ...

  transaction.commit();
}

ゲッター/セッターでのフラッシュ

バッチバッファーにあるBeanの場合、生成されたプロパティまたは「ロードされていない」Idプロパティでゲッター/セッターを呼び出すと、フラッシュがトリガーされます。

try (Transaction transaction = database.beginTransaction()) {
  transaction.setBatchMode(true);

  // bean goes to batch buffer
  myBean.save();
  ...

  // will trigger flush if id is an "unloaded" property
  // and myBean is in the buffer (not flushed)
  long id = myBean.getId();

  // will trigger flush if myBean is in the buffer (not flushed)
  Instant whenCreated = myBean.getWhenCreated();

  ...

  transaction.commit();
}

明示的なflush()

バッチされたステートメントがすべて実行されていることを確認したい場合は、明示的なtransaction.flush()を実行することをお勧めします。これは通常、すべてのSQLステートメントが実行され、アプリケーションロジックのその時点ですべてのDB制約がテストされていることを意味します。

try (Transaction transaction = database.beginTransaction()) {
  transaction.setBatchMode(true);

  // bean goes to batch buffer
  myBean.save();
  ...


  // ensure all SQL statements are executed which means that
  // all DB constraints (unique, foreign key etc) are tested
  transaction.flush();


  // carry on with stuff ...
  ...

  transaction.commit();
}

DatabaseConfigによる設定

// use JDBC batch by default
databaseConfig.setPersistBatch(PersistBatch.ALL);

databaseConfig.setPersistBatch(PersistBatch.ALL)を設定して、JDBCバッチモードがすべてのトランザクションでデフォルトで使用されるようにすることができます。

// default batch size
databaseConfig.setPersistBatchSize(50);

グローバルなデフォルトのバッチサイズは、databaseConfig.setPersistBatchSize()で変更できます。デフォルトは20です。

// update all loaded properties or just dirty properties
databaseConfig.setUpdateAllPropertiesInBatch(true);

バッチ更新を使用する場合、更新にダーティプロパティを含めるか、ロードされたすべてのプロパティを含めるかのオプションがあります。ダーティプロパティを選択した場合、更新ステートメントに含まれるプロパティは少なくなりますが、(アプリケーションロジックが更新対象のすべてのBeanで同じプロパティを更新しない場合)実行される個別の更新ステートメントが増える可能性があります。