トランザクション

Isarにおいて、トランザクションは複数のデータベース操作を1つの作業単位にまとめます。Isarの大半の処理は、暗黙のうちにトランザクションを利用しています。IsarのRead & write操作は、ACIDopen in new windowに準拠しており、トランザクションは、エラーが発生すると自動的にロールバックされます。

明示的なトランザクション

明示的なトランザクションでは、データベースの整合性のあるスナップショットを取得したり、トランザクションの継続時間を最小限にするようにします。また、トランザクションの中でネットワークの呼び出しやその他の長時間実行される操作を行うことは禁じられています。

トランザクション(特に書き込みトランザクション)にはコストがかかるので、連続する操作は常に1つのトランザクションにまとめるようにしましょう。

トランザクションには、同期と非同期があります。同期トランザクションでは、同期操作のみを使用することができて、非同期トランザクションでは、非同期操作のみを使用することができます。

ReadRead & Write
同期.read().write()
非同期.readAsync().writeAsync()

読み取りトランザクション

明示的な読み取りトランザクションは任意ですが、Atomic(原子性の)読み取りを可能にし、トランザクション内のデータベースの一貫した状態に依存することができます。内部的には、Isarはすべての読み込み操作に対して常に暗黙的な読み込みトランザクションを使用します。

ヒント

非同期読み取りトランザクションは、他の読み取りおよび書き込みトランザクションと並行して実行されます。かなりイケてますよね?

書き込みトランザクション

読み込み操作とは異なり、Isarでの書き込み操作は明示的なトランザクションに包まれる必要があります。

書き込みトランザクションが正常に終了すると、自動的にコミットされ、すべての変更がディスクに書き込まれます。もしエラーが発生した場合、トランザクションは中断され、すべての変更がロールバックされます。トランザクションは "all or nothing"です。トランザクション内のすべての書き込みが成功するか、データの一貫性を保証するために何も実行されないかのどちらかである。

警告

データベース操作に失敗した場合、トランザクションは破棄され、それ以降使用してはいけません。たとえDartでエラーを捕捉したとしてもです。

@collection
class Contact {
  late int id;

  String? name;
}

// GOOD
await isar.writeAsync((isar) async {
  for (var contact in getContacts()) {
    await isar.contacts.put(contact);
  }
});

// BAD: トランザクションの中にforループを移動させましょう。
for (var contact in getContacts()) {
  await isar.writeAsync((isar) async {
    await isar.contacts.put(contact);
  });
}