關系數據庫映射(行為模式之工作單元)


[問題域]

正常情況下,如果使用Data Mapper解決了Domain對象和數據庫分離的目的,使用時,如果每當一個Domain對象創建、修改或刪除時,最簡單的方式就是立即對數據庫進行更新操作,但是這樣會對數據庫產生大量的調用動作。如果不這樣做,就必須記錄下Domain對象的各種修改動作,以保證最后提交時,對數據庫進行相應的更新,保持Domain對象和數據庫的一致性。

[解決方案]


找一個處所保存Domain對象的各種變化,最后提交時,就知道應該要做什么修改,并最終寫入數據庫。而這個處所可以稱之為工作單元(Unit of work),使用這種方式被命令為工作單元模式(參考[Martin Fowler企業架構模式])。


工作單元模式(Unit of work)

根據以上描述可知,工作單元模式包括兩個主要方面:

1. 記錄操作過的各種Domain對象
2. 同步到數據庫中





我們先來看看如何記錄操作過的各種Domain對象


1.由調用者注冊。比如:調用者創建一個Domain對象時,同時通知工作單元,執行了更新操作。

  缺點:有程序開發者主動控制,人是最靠不住的。
  有點:可以主動決定是否注冊,(也就是決定把Domain更改是否寫入數據庫)

2.由Domain對象注冊。
比如:Domain對象中的Create方法中比如加入通知工作單元的代碼,工作單元可以作為參數傳入,或者固定的地方可以獲取(如ThreadLocal保存)。

  缺點:也是需要由人在各個Domain對象的各種操作中加入固定通知工作單元代碼。
  優點:當然具有一致性,同時就可以采用AOP的思想統一操作(比如Proxy,Minxin等)

3.工作單元控制器。
總的思路是,工作單元控制所有的讀操作,讀取對象的時候,對它進行注冊為Clean的,并產生一個拷貝,提交時,對比一下哪些字段進行了改變,然后再更新。對于不想拷貝的對象則需要主動進行注冊。(TOPLink使用此方式)

  缺點:不需要拷貝的對象需要主動注冊,否則一律拷貝一個。
  優點:對Domain對象的改變只進行了有選擇的更新。


接下來討論工作單元同步到數據庫的問題:

1.更新順序

如果數據庫允許,只在事務提交時檢查引用完整性,而不是每次SQL都檢查,則隨便怎么用都可以。如果數據庫不允許,則在工作單元中則根據元數據(metadata)指定的順序執行更新數據庫的操作。

2.批量更新

如果有一些列的更新,刪除或新增操作,則可以在工作單元中,作為一個單條語句發送請求。


[結論]

工作單元最大的好處就是把各種復雜的操作保存在一個固定的地方。這種模式可以應用于所謂有類似需求的地方。


參考資料:


Patterns of Enterprise Application Architecture (author:Martin Fowler)