トランザクションからセーブポイントへの SQLite の移行
-
12-12-2019 - |
質問
私の SQLite
ベースのアプリケーションは現在、ロールバックとパフォーマンスの向上の両方の目的でトランザクションを使用しています。すべてのトランザクションをセーブポイントに置き換えることを検討しています。その理由は、アプリケーションがマルチスレッドであるためです (はい、 sqlite
スレッドセーフに構成されているため)、場合によっては、トランザクションが 2 つのスレッドによって同時に (同じデータベース上で) 開始されることがあります。
- それをやらない理由があるのでしょうか?
- 注意しなければならない落とし穴はありますか?
- ただ交換するだけですか
BEGIN
,COMMIT
,ROLLBACK
とSAVEPOINT xyz
,RELEASE SAVEPOINT xyz
,ROLLBACK TO SAVEPOINT xyz
?
解決
It there a reason NOT to do it?
はい。あなたが概説した問題は何一つ解決されません。セーブ ポイントは主に、データの部分的なロールバックを実行できるようにするために使用されます。外側のトランザクションまたはセーブポイントが実際にコミットされるものです。最も外側のセーブポイントが解放されて DB が更新されるまで、実際には何も完全には保存されません。標準トランザクションで発生するのと同じ問題に戻ってしまいます。
Are there any pitfalls I need to be aware of?
はい。2 つの異なるスレッドで同じデータを更新している場合、マルチスレッド アプリケーションのトランザクションやセーブポイントは非常に簡単にデッドロックする可能性があります。これが問題の核心だと思います。この点では両者に違いはありません。各スレッドで何を更新しているのかを認識し、それに応じて同期する必要があります。
つまり、部分的なトランザクション ロールバックを行う必要がない限り、セーブポイントは実際にはあまり役に立ちません (名前が付けられているという事実を除けば)。
ここには特効薬はありません。アプリケーションと複数のスレッドで更新される可能性のあるデータを真剣に分析し、必要に応じてアプリケーションに同期を追加する必要があるようです。