Web開発でバッチ処理を考慮して排他制御を考えるのは非常に難しいです。
例えば、商品を購入してキャンセルしたいのにバッチ処理が先に動いてしまってキャンセルする前に商品が発送されてしまったというケースも考えられます。
バッチ処理の排他制御の難しいポイント
オンライン処理で楽観ロックや行ロックをしてしまっている場合、バッチ処理全体が異常終了してしまう。逆にバッチ処理でロックをしてしまってもオンライン処理が待たされてしまいます。
こうした場合の対処法としてはいくつかありますが、どれも現実的ではなかったり確実ではないでしょう。
オンライン処理とバッチ処理の時間で分ける方法
夜間にシステムを操作できなくして、その間にバッチ処理を流す方法です。これならオンライン処理とバッチ処理で競合が発生する余地がありません。
デメリット
最近は、24時間稼働することが必須のシステムが当たり前になってきています。そうするとこの方法は採用できません。
データで分ける方法
ステータスを使用してバッチ処理の対象であるのか、オンライン処理の対象であるかを分ける方法です。
時間で分けてデータで分ける方法
商品の購入した後のキャンセルを0時までは受け付けるといった方法があります。
バッチ処理とオンライン処理の比較
バッチ処理
非インタラクティブ(対話的ではない)なので基本的には行ロックによる排他制御を行うことが普通です。(ただ、状況に応じて悲観ロックや楽観ロックも使います。)
オンライン処理
悲観ロック、楽観ロック、行ロックを使い分けます。
現実的な対策
オンライン処理が終わるまで待ちつつ排他制御をする方式(オンライン優先)
オンライン処理が頻繁に起こるようであれば最悪バッチ処理のタイムアウトも考えられるので注意しましょう。
利用シーン
- オンライン処理とバッチ処理の競合が少ない場合
- バッチ処理に時間がかかっても問題ない場合
オンライン処理のロック解除を待たずにバッチ処理でロックを強制的に解除する方式(バッチ優先)
オンライン側で排他エラーが発生してしまいます。
利用シーン
- オンライン処理とバッチ処理の競合が多い場合
- バッチ処理の時間厳守が要求になっている場合
オンラインでロックされているものは無視する方式
利用シーン
- バッチ処理の処理タイミングが次回でも良い場合
バッチ処理のトランザクションの単位
バッチ処理で一括処理するとした場合に、トランザクションの単位はまとめて実施する単位ではなく1件ずつをトランザクションの対象とします。そこは注意しましょう。
この記事へのコメントはありません。