持久化機制生成唯一辨別
若從DB擷取一個序列值(Sequence)或遞增值,結果總是唯一。根據辨別所需範圍,資料庫可生成2位元組、4位元組和8位元組的唯一辨別。在Java中的這些大小整數分别可表示
- 32,767
- 2,147,483,647
- 9,223,372,036,854,775,807
種不同辨別值。
缺陷
性能。
從DB擷取辨別比APP生成慢得多。一種解決方法是将資料庫序列緩存在APP,比如緩存在資源庫。
這固然是一種好方法,但若伺服器節點需重新開機,那麼将失去很大一部分辨別值區間。若丢失區間無法接受或隻需相對較小辨別值(2位元組整數),這緩存機制便不實用,也沒必要。當然可以找回丢掉的辨別值區間,但可能引入新麻煩。
如果可使用延遲生成,那緩存辨別便不是問題。以下是如何使用Hibernate和Oracle的序列來生成辨別:
<id name="id" type="long" column="product_id">
<generator class="sequence">
<param name="sequence">product_seq</param>
</generate>
</id>
在采用MySQL的自增列時配置如下
<id name="id" type="long" column="product_id">
<generator class="native"/>
</id>
這種方式的性能是很好的,同時配置Hibernate映射也是簡單的。
3.1.3 另一個限界上下文提供唯一辨別
若另一個限界上下文用于給實體辨別指派,那需要對每個辨別進行查找、比對和指派。
最重要的是精确比對。此時使用者需提供一或多種屬性,比如賬戶、使用者名和E-mail位址,以精确定位需要比對的結果。
通常比對的輸入是模糊的,導緻多個查詢結果,此時使用者需要手動選擇,如圖
- 從外部系統中擷取需要查找的唯一辨別。使用者界面中可顯示唯一辨別(本圖),也可不顯示
-
DDD領域驅動設計實戰 - 建立實體身份辨別的常用政策(下) - 使用者輸入了模糊查找資訊,通過調用外部限界上下文的API,傳回的結果可能是0、1或多個比對對象。接着使用者要在結果中選擇某特定對象。所選對象的身份辨別将作為本地辨別。外部實體的一些額外屬性也可能被複制到本地實體。
對象同步可能是個問題。外部對象的改變将如何影響本地對象?如何知道所關聯的對象已經改變了呢?
可通過事件驅動架構和領域事件解決。本地限界上下文訂閱外部系統中的領域事件,當本地上下文接收到外部系統的事件通知時,它将相應更新本地對象。有時同步事件可能由本地上下文發出,外部系統在接受到該事件時同樣會做相應的更新操作。
要達到這樣的目的并不容易,但這樣做能夠建立出更加具有自治性的系統。可将對象查找限定在本地對象中。這并不是說将外部對 象緩存在本地系統中,而是将外部概念翻譯成本地限界上下文中的概念。
這是最為複雜的辨別建立政策。要維護本地實體,我們不但需要考慮由本地 領域行為所導緻的改變,還需要将外部系統也考慮在内。是以在使用這種政策時,應持保守态度。
參考
《實作領域驅動設計》