次のような長期にわたる複数行の更新があります。
UPDATE T set C1 = calculation(C2) where C1 is NULL
テーブルが大きい場合、この更新には数秒または数分かかる場合があります。この間、このテーブルの他のすべてのクエリは、接続タイムアウトの期限が切れた後、「データベースがロックされています」で失敗します (現在、私のタイムアウトは 5 秒です)。
この更新クエリを、たとえば 3 秒後に停止してから再開したいと思います。うまくいけば、数回再起動すると、テーブル全体が更新されます。別のオプションは、他のリクエストを行う前にこの更新クエリを停止することです (これにはプロセス間の協力が必要ですが、実行可能な場合があります)。
しかし、以前に更新されたすべてのレコードをロールバックせずに更新クエリを停止する方法が見つかりません。割り込みを呼び出して、progress_handler から非 0 を返してみました。これらのアプローチは両方とも、更新コマンドを中止し、すべての変更をロールバックします。そのため、sqlite はこの更新をトランザクションとして扱っているように見えますが、この場合はすべての行が独立しているためあまり意味がありません。しかし、行ごとに新しいトランザクションを開始することはできません。
interrupt と progress_handler が役に立たない場合、他に何ができますか?
LIMIT と WHERE custom_condition(C1) で UPDATE も試しました。これらのアプローチにより、更新を早期に終了できますが、通常の更新よりも大幅に遅くなり、特定の時間 (別の接続タイムアウトが期限切れになる前) にクエリを終了できません。
他のアイデアはありますか?この複数行の更新は非常に一般的な操作であるため、他の人が適切な解決策を持っていることを願っています。