同期処理と非同期処理の境界は操作の成立条件から引く

ある処理を元のトランザクションで同期的に実行するか、メッセージバスを介して非同期に実行するかは、その処理の所要時間や重要度だけでは決まらない。 その処理の失敗時に元の操作も失敗として取り消す必要があるかを問うと、境界を判断できる。

失敗時に元の操作も取り消す必要がある処理は、元の操作を成立させる処理である。 たとえば「確定した注文には必要な在庫が確保されている」を即時に守るなら、注文確定と在庫確保の片方だけが成功した状態をコミットできない。 この二つは同じ整合性境界に属する。 どの状態を同じ境界へ含めるかは、強整合を要求する不変条件の所有者から考える。

一方、失敗しても元の操作を成立させてよい処理は、成立した事実から派生する反応として分離できる。 注文確認メール、検索索引の更新、分析用イベントの記録は、遅延や再試行が発生しても注文そのものを取り消す理由にはならない。 このような処理をメッセージバスへ出すと、元の操作は後続処理の完了を待たずに確定できる。

ただし、元の操作の成立に必要でも、外部サービスをまたぐ処理は一つのデータベーストランザクションへ含められないことがある。 その場合は、未完了の状態を隠して一括成功を装うのではなく、「注文受付済み」「決済完了」「注文確定」のように業務上の状態を分ける。 それぞれの状態遷移を局所的なトランザクションで守り、失敗時には再試行か補償によって次の状態を決める。

したがって、非同期化は本質的な処理を単に後回しにすることではない。 元の操作の成立条件をトランザクションに残し、成立後の反応を外へ出す設計判断である。

#transaction #asynchronous-processing #message-bus #consistency