2016-10-27 6 views
4

私が構築しているアプリケーションでは、特定の操作を実行する集約のグループを選択する必要がある多くのシナリオがあります。例えば、私はReminder集団の束が期限切れ方針を満たしていれば(それが1つしかない)、期限切れとしてマークしなければならないかもしれません。不変量についてはリポジトリを信頼すべきでしょうか?

私はReminderExpirationPolicyドメインサービスを持っており、リマインダを配信する前に常に適用されます。それはSqlReminderRepository.findRemindersToExpireメソッド内でもReminder.expire集計のメソッド内のSQL述語として存在するよう

reminderRepository.findRemindersToExpire().forEach(function (reminder) { 
    reminder.expire(clockService.currentDateTime()); 
}); 

有効期限ポリシーが現在重複している:このポリシーは、のようなものはありません。

質問への答えは強く(そこには間違いなく長所と短所すべきである - そしておそらく広く採用されている練習)opiniatedすることができるが、私は単にReminder.expire方法のみReminderExpirationPolicyプロセスの一部として呼び出されますことを信頼すべきですリポジトリの実装が正しいリマインダーセットを返すことを信頼するか、またはReminder集合体内の不変量を保護する必要がありますか?

注:単一のトランザクションで複数の集約を変更することは最適ではなく、スケーラビリティを妨げることになりますが、私の場合は最も実用的な解決策です。

+0

リマインダーは通常の有効期限まで手動で有効期限切れにできませんか?私は通常、時間を意味する不変量には注意が必要です。なぜなら、それは扱うのが最も難しい制約です。 – guillaume31

+0

@ guillaume31いいえ、手動で期限切れにすることはできませんが、有効期限と呼ばれることはありませんが、送信を防ぐ他の手段があります。リマインダーが有効なルールは非常に厳しいため、有効期限は自動化されます。これらは税申告通知であり、財政期末(FPE)前および後に通知が送信されます。 FPEが終了している場合、 'before'リマインダーを送信することは意味がありません。 – plalx

+0

通常、期限切れは、長時間のリマインダの送信を妨げるシステムの問題があった場合、またはあまりに長い間訂正されなかった場合にのみ発生します。 – plalx

答えて

3

私は単にReminder.expire方法のみReminderExpirationPolicyプロセスの一部として呼び出され、リポジトリの実装が期限切れにリマインダの正しいセットを返しますか、私はまた、内不変を保護する必要があることを信頼してしまいますことを信頼すべきですリマインダー自体は集計されますか?

短い回答:あなたは後方です。 は、リマインダー内の不変量を保護する必要があります集約;ポリシーをクエリ仕様として使用することはオプションです。

実現する重要なことは、シナリオでは、ポリシーをクエリ仕様として使用することが実際にはオプションであることです。永続性の懸念を排除すると、これを行うことができるはずです。これを行うことができるはずです。ビジネスインバリアントに違反すると、状態を変更することを拒否する集計が減少します。一般に

、この区別は重要である理由は、あなたがリポジトリを照会することによって得ることができる任意のデータが古いであるということです - あなたの検索後に集計を更新し、あなたと一致を実行している別のスレッドがあるかもしれません実行されたが期限切れコマンドが実行される前に実行され、ポリシーがもはや満たされないように集計を変更することが一致した場合、期限切れコマンドは後に来て不変量に違反する脅威になります。

とにかくこの種の競合状態に対して集合体を保護する必要があるため、クエリのポリシーをチェックすることはオプションです。

もちろん、通常の操作の過程で、失敗すると予想されるコマンドを送信しないでください。

実際に何が起こっているのですか、ちょっとしたことがあると、期限切れコマンドとクエリが同じポリシーを使用していますが、コマンド実行パスがwriteModel状態がポリシーを満たしているかどうかを評価している場合、 readModel状態はポリシーを満たします。したがって、実際には論理が重複しているわけではありません。それぞれ異なる引数を使用しています。私の仮定は、あなたとは異なりますが

は、限りから、私は凝集体がロードされた後、データが古くなった場合でも、(楽観的ロックと仮定)と私は内の有効期限ルールを強制しないことを見ることができるようにということです集約では、並行処理の競合のために操作が失敗することがあります。

はい、コマンドを処理する集約のバージョンがポリシーのテストに使用されたバージョンと同じであることが保証されている場合、同時書き込みによって保護されます。

追加の考慮事項は、カプセル化の利点の1つを失うことです。ポリシーチェックが集約で行われる場合、集約を期限切れにする可能性のあるすべてのコードパスもポリシーを評価する必要があります。アグリゲートがポリシーをチェックするために呼び出し元に依存している場合(「貧血ドメイン」モデルの亜種)、その保証は得られません。

+0

ええ、それは私が思っていた、それはおそらくそれを見て正しい方法です。しかし、私の仮定があなたのものと違うところでは、私が見ることができる限り(楽観的なロックを前提としています)、集約がロードされた後にデータが失効しても、集計内で失効ルールを強制しない場合でも、並行性の競合のために引き続き失敗します。したがって、ルールがリポジトリ内で正しい場合、データが変更されなかった場合にのみルールが適用されることを保証できます。つまり、リポジトリ内のクエリ条件だけで不変量を保護できます。 – plalx

+0

つまり、クエリは「リマインダー」の境界内に存在するデータのみに依存していると仮定します。 – plalx

+0

これは別の質問ですが、ポリシーや仕様を自動的にASTに変換してからSQLに戻すか、その道を踏み出すことで自動的に翻訳しようとしますか? – plalx

関連する問題