トランザクションを扱う
from DMMF: Persistence
LT;DR
一般的に「1 つの集約 = 1 つのトランザクション」だが、場合によっては複数の集約を更新しなければならないケースも
データストアが トランザクション を機能として提供している場合、それを利用する
提供していない場合は、補償アクション(補償トランザクション)が必要
hr.icon
これまでは「1 つの集約 = 1 つのトランザクション」という形を取っていた
同じコンテキストの集約間の整合性#669a1b7475d04f00002ec3f9
一般的には「1 つのトランザクションにつき 1 つの集約のみを更新する」
しかし、複数の集約を更新しなければならないケースもある
e.g. 2 つの口座間の送金
この場合は トランザクション が必要
1. データストアがトランザクションが利用可能なケース
e.g. 普通の RDBMS を利用している場合など
API からトランザクションを張る
code:fsharp
let connection = new SqlConnection()
let transaction = connection.BeginTransaction()
markAsFullyPaid connection invoiceId
markPaymentComplete connection paymentId
transaction.Commit()
DBMS によっては、複数の操作を 1 回の呼び出しにまとめないとトランザクションできないこともあるっぽい…
radish-miyazaki.icon は見たことない…
2. データストアがトランザクションを利用できないケース
e.g. 異なる RDBMS を使っているケース、外部サービスを利用している場合など
スターバックスは2フェーズコミットを使わない にあるように、ビジネスでは異なるシステム間のトランザクションは必要としていないはず
オーバーヘッド や 調整コストが重く、時間がかかるため
代わりに、大抵のことはうまくいくと想定したうえで、不整合 を検出するための調整プロセスやエラーを修正するための 補償アクション(補償トランザクション)を行う
e.g.
code:fsharp
markAsFullyPaid connection invoiceId
let result = markPaymentComplete connection paymentId
match result with
| Error err ->
// エラーを補償する
unmarkAsFullyPaid connection invoiceId
| Ok _ -> ...