Isarデータベースライブラリを使用してDartまたはFlutterアプリケーションを開発する際、特定の状況で「IsarError: Cannot perform this operation from within an active transaction. Isar does not support nesting transactions.」というエラーが発生することがあります。この記事では、このエラーの原因とその対処方法を詳しく説明します。
エラーが発生したコード
このエラーは、Isarのトランザクション中にIsarLinksを使用してサブリストのアイテムに対して検索クエリ(例えばwhere
クエリ)を行う場合に発生することがあります。例えば、タスクとサブタスクを管理する以下のようなモデルがあるとします。
()
class Task {
Id id = Isar.autoIncrement;
late String name;
final subTasks = IsarLinks<SubTask>();
}
()
class SubTask {
Id id = Isar.autoIncrement;
late String name;
late DateTime dueDate;
}
このモデルにおいて、以下のようなトランザクション内でサブタスクに対して検索を行うとエラーが発生します。
await isar.writeTxn(() async {
var ret = task.subTasks
.where((elem) => elem.dueDate == dateTime).firstOrNull;
// その他の処理
});
エラーの原因
おそらく、IsarLinksのリンク集合にwhere
を使用すると、内部で新たなトランザクションが暗黙のうちに開始され、既に開始されているトランザクションにネストしてしまうようです。Isarはネストしたトランザクションをサポートしていないため、この状況はエラーを引き起こします。
解決策
対処法として、where
を直接使用するのではなく、Isarが提供するより正式なクエリAPIを使用して検索を行います。以下は修正後のコードです。
await isar.writeTxn(() async {
var ret = await task.subTasks
.filter()
.dueDateEqualTo(dateTime)
.findFirst();
// その他の処理
});
この方法では、filter
を用いて具体的な条件を指定し、findFirst
で条件に合致する最初の要素を取得します。このクエリはトランザクション内部で安全に実行され、ネストされたトランザクションを生成しません。
まとめ
Isarで「IsarError: Cannot perform this operation from within an active transaction.」というエラーに遭遇した場合は、検索クエリの書き方を見直して、内部で新たなトランザクションが開始されることがないように注意しましょう。
0 件のコメント:
コメントを投稿