SQLiteを使用するアプリケーションは小さく、SQLiteには独自のセマンティクスがあることを理解しています。ここに掲載されている他の解決策は、この特定の設定で必要な効果をもたらす可能性がありますが、私の見解では、これまで読んだすべての解決策は根本的に正しくないため、避ける必要があります。
通常の環境では、ユーザー入力のトランザクションを保持することは絶対に避けてください。中間データを格納する必要がある場合、これを処理する方法は、この目的のために情報をスクラッチテーブルに書き込んでから、アトミックトランザクションですべての情報を書き込もうとすることです。トランザクションを保持すると、マルチユーザー環境でデッドロックと同時実行の悪夢が発生します。
ほとんどの環境では、トランザクション内でSELECTを介して取得されたデータが繰り返し可能であると想定することはできません。例えば
SELECT Balance FROM Bank ...
UPDATE Bank SET Balance = valuefromselect + 1.00 WHERE ...
UPDATEに続いて、残高の値が変更される可能性があります。トランザクション内で最初に銀行に関心のある行を更新することでこれを回避できる場合があります。これにより、行がロックされ、トランザクションが完了するまで更新によって値が変更されないことが保証されます。
ただし、この場合の一貫性を確保するためのより良い方法は、更新のWHERE句のデータの内容に関する仮定を確認し、アプリケーションの行数を確認することです。上記の例では、「UPDATE Bank」の場合、WHERE句は残高の予想される現在の値を提供する必要があります。
WHERE Balance = valuefromselect
期待されるバランスが一致しなくなった場合、WHERE条件も一致しません。UPDATEは何も行わず、rowcountは0を返します。これは、同時実行の問題があったことを示しており、他の何かがデータを変更しようとしていないときに、操作を再実行する必要があります。同時に。