PHPスクリプトでは、 Ingrore_user_abort(true)は、クライアントが中断されている場合でも、スクリプトを実行を継続できる非常に実用的な機能です(ユーザーがブラウザを閉じたり、ネットワークが切断されたりするなど)。この機能は、長期にわたるタスク(レポートの生成、バッチの更新、プッシュ通知など)を処理するときに特に重要です。ただし、データベーストランザクションと組み合わせて使用される場合、タスク実行の整合性と一貫性を確保する方法は、無視できない課題です。
INGRORE_USER_ABORT(TRUE)の目的は、PHPエンジンに「クライアントが切断されているかどうかを無視する」ように指示し、スクリプトを実行し続けることです。デフォルトでは、PHPは、関数が明示的に呼び出され、 trueが渡されない限り、クライアントの切断を検出するときにスクリプト実行を終了します。
<span><span><span class="hljs-title function_ invoke__">ignore_user_abort</span></span><span>(</span><span><span class="hljs-literal">true</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">set_time_limit</span></span><span>(</span><span><span class="hljs-number">0</span></span><span>); </span><span><span class="hljs-comment">// スクリプトが無制限に実行されることを許可します</span></span><span>
</span></span>
set_time_limit(0)は通常、タイムアウトによるスクリプトが壊れないようにするために使用されます。
データベーストランザクションは、SQL操作のセットが成功するか、すべて失敗したことを保証できます。これはいわゆる原子性です。トランザクションのもう1つの重要な機能は、「耐久性」です。つまり、コミットされると、データは永久に保存されます。
<span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">beginTransaction</span></span><span>();
</span><span><span class="hljs-comment">// 一連のデータベース操作</span></span><span>
</span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">commit</span></span><span>(); </span><span><span class="hljs-comment">// または $db->rollBack();</span></span><span>
</span></span>
中断される可能性のある長いタスクでデータベーストランザクションを使用すると、不注意に処理された場合、次の問題が発生します。
接続は<br>をコミットせずに切断されます トランザクションが開かれた後にスクリプトが突然中止した場合(ユーザーがINGRORE_USER_ABORTを設定しないためにユーザーが切断されているためにスクリプトが終了した場合)、トランザクションの操作はデータベースによって自動的にロールバックされ、予想される操作が実行されません。
論理的中断は、ビジネスデータの矛盾を引き起こします<br> スクリプトロジックは、その後の操作を完了するためにトランザクションに依存しています。取引がコミットされる前に予期せず中断された場合、ビジネス状態全体が「半完全な」状態にある可能性があります。
DatabaseでのトランザクションにIngrore_user_abortを使用するときに、タスク実行の整合性を確保するためのいくつかの実用的な戦略を以下に示します。
<span><span><span class="hljs-title function_ invoke__">ignore_user_abort</span></span><span>(</span><span><span class="hljs-literal">true</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">set_time_limit</span></span><span>(</span><span><span class="hljs-number">0</span></span><span>);
</span></span>
これらの2行のコードは、タスクロジックが開始される前に実行され、クライアントの切断またはタイムアウトのためにスクリプトが中断されないようにします。
トライアル/キャッチ構造でトランザクションをラップして、例外でロールバックを確保し、データが汚染されていないことを確認します。
<span><span><span class="hljs-keyword">try</span></span><span> {
</span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">beginTransaction</span></span><span>();
</span><span><span class="hljs-comment">// データベース関連操作を実行します</span></span><span>
</span><span><span class="hljs-title function_ invoke__">doSomething</span></span><span>();
</span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">commit</span></span><span>();
} </span><span><span class="hljs-keyword">catch</span></span><span> (</span><span><span class="hljs-built_in">Exception</span></span><span> </span><span><span class="hljs-variable">$e</span></span><span>) {
</span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">rollBack</span></span><span>();
</span><span><span class="hljs-title function_ invoke__">error_log</span></span><span>(</span><span><span class="hljs-string">"トランザクションは失敗しました:"</span></span><span> . </span><span><span class="hljs-variable">$e</span></span><span>-></span><span><span class="hljs-title function_ invoke__">getMessage</span></span><span>());
}
</span></span>
キーノードでログを作成すると、開発者がタスクの実行が完了したかどうかを追跡するのに役立ちます。特に、トランザクションの提出の前後のキーポイントでログを作成すると、予期しない中断がビジネスに与える影響を分析するのに役立ちます。
<span><span><span class="hljs-title function_ invoke__">file_put_contents</span></span><span>(</span><span><span class="hljs-string">'/tmp/task.log'</span></span><span>, </span><span><span class="hljs-string">"ミッションが始まります\n"</span></span><span>, FILE_APPEND);
</span><span><span class="hljs-comment">// ...</span></span><span>
</span><span><span class="hljs-title function_ invoke__">file_put_contents</span></span><span>(</span><span><span class="hljs-string">'/tmp/task.log'</span></span><span>, </span><span><span class="hljs-string">"トランザクションの提出が完了します\n"</span></span><span>, FILE_APPEND);
</span></span>
タスクの繰り返しまたは部分的な実行を避けるために、長いタスクにステータスフィールド(処理、完了、失敗など)を長いタスクに導入します。
<span><span><span class="hljs-comment">// 标记ミッションが始まります处理</span></span><span>
</span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">"UPDATE tasks SET status = 'processing' WHERE id = <span class="hljs-subst">$taskId</span></span></span><span>");
</span><span><span class="hljs-comment">// ビジネスロジックを実行します...</span></span><span>
</span><span><span class="hljs-comment">// タスクの完了をマークします</span></span><span>
</span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">"UPDATE tasks SET status = 'done' WHERE id = <span class="hljs-subst">$taskId</span></span></span><span>");
</span></span>
トランザクションと組み合わせて、状態の変更がビジネスロジックと一致していることを確認します。
予期しない割り込みによって引き起こされる「未完成の」タスクの場合、タイムされたスクリプトを介して更新されていないデータベースのレコードを確認し、自動的に再試行またはアラームすることができます。
INGRORE_USER_ABORTは、途切れないタスクを提供する機能を提供しますが、それだけでデータベース操作の整合性を保証することはできません。トランザクションメカニズムを組み合わせるときは、例外キャプチャ、状態管理、ログトラッキングなどのさまざまな手段を通じてビジネスの一貫性と回復を確保する必要があります。不安定なネットワークまたは予期しない中断に直面して、安定したビジネスオペレーションを維持できるのは、合理的で障害のあるシステムのみです。