5

DDD では、集約ルートにリポジトリを含めることができます。Order集約を取りましょう。これは、非永続的な対応するOrderRepositoryと永続的な対応するOrderUoWです。また、注文された製品の在庫を追跡するProductVariant集約もあります。ProductVariantRepositoryProductVariantUoWを持つことができます。

Order と ProductVariant が機能する方法は、注文が永続化される前に、在庫がチェックされるというものです。在庫がある場合、注文は OrderUoW.Commit() を呼び出すことによって保持されます。はい、ProductVariantUoW.Commit() が次に呼び出され、製品の在庫が更新されます。

残念なことに、ユーザーが同じ製品を短時間で購入した場合、事態は悪化する可能性があります (これを、2 人のユーザーが同じ製品を購入している Web アプリと考えてください)。これで、2 番目のユーザーのトランザクション全体が、作成したばかりの注文を元に戻すことによって失敗するはずです。OrderUoW を呼び出して変更をロールバックする必要がありますか (注文はデータベースから削除する必要があります)。または、両方の UoW.Commit() 操作をトランザクション スコープに配置して、1 つの commit() が失敗すると変更がロールバックされるようにする必要がありますか? それとも、両方のリポジトリ (Order、ProductVariant) に UoW のみが必要で、トランザクション スコープが 1 つだけ必要ですか?

複数のリポジトリが関係する場合、トランザクションはどのように処理されるのでしょうか?

4

3 に答える 3

1

私たちが尋ねることができる質問は、誰が次のことをしているのかということです:

Order と ProductVariant が機能する方法は、注文が永続化される前に、在庫がチェックされるというものです。在庫がある場合、注文はOrderUoW.Commit() を呼び出すことによって保持されます。はい、ProductVariantUoW.Commit() が次に呼び出され、製品の在庫が更新されます。

この種の作業はサービス層に属していると主張する人もいます。これにより、サービス層は集約オブジェクトを横断するものを単一のトランザクションに入れることができます。

http://www.infoq.com/articles/ddd-in-practiceによると:

一部の開発者は、設計が不十分な DAO クラスでトランザクションを管理することを好みます。これにより、トランザクション制御がきめが細かくなりすぎて、トランザクションが複数のドメイン オブジェクトにまたがるユース ケースを柔軟に管理できなくなります。サービス クラスはトランザクションを処理する必要があります。この方法では、トランザクションが複数のドメイン オブジェクトにまたがる場合でも、ほとんどのユース ケースでサービス クラスが制御フローを処理するため、サービス クラスはトランザクションを管理できます。

単一のトランザクションを使用する代わりに、ProductVariant を使用して在庫を請求し、必要なすべての在庫品目が利用可能であれば、注文を確定できると思います。そうでない場合 (つまり、注文に必要なすべての製品を請求できない場合)、補償トランザクションを使用して正常に請求された在庫を返品する必要があります。その結果、注文のコミットに失敗した場合、在庫の一部が一時的に他の注文に利用できないように見えますが、分散トランザクションなしで作業できるという利点があります。

それでもなお、このロジックは、DAO クラスではなく、サービス層に属しています。

于 2013-01-05T01:06:08.200 に答える
1

単一の UoW を使用できる場合は、その方が簡単なので使用してください。

リポジトリが異なる DB にある場合 (または、1 つがファイルベースで他がそうでない場合)、複数の UoW を使用せざるを得なくなる可能性がありますが、ロールバック コマンドも作成することになります。UoW1 が変更を SqlRepo に保存する場合わかりましたが、UoW2 が FileRepo への変更の保存に失敗した場合は、SqlRepo をロールバックする必要があります。回避できるのであれば、ロールバック コマンドをわざわざ書く必要はありません。

于 2015-04-10T10:15:06.580 に答える