接下來這篇我們要來談談,我個人覺得很重要的 UnitOfWork,這個東西很多人知道要,但是應該也不少公司沒在實作,因為沒有發生問題,就一切平安呢 ~
Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.
事實上你幾乎可以想成是資料庫 transaction 的概念,只是某些方面它是以將 db 的概念移除,想要以 domain 層級來達成 transaction 的事情。
追蹤所有被新增、修改、刪除的 Domin Model instance,並在 commit 時一次送出這些修改。
我們到了今天總共學到了不少層級加 pattern,那我們是要以那個層級中的那個部份為單位呢 ? service、domain model、row data gateway、table data gateway、repository、model ( active record )、data mapper 呢 ?
說實話我單看書中的範例,它是在 service 中註冊,然後以 data mapper 為單位。
class EditAlbumScript...
public static void updateTitle(Long albumId, String title) {
UnitOfWork.newCurrent();
Mapper mapper = MapperRegistry.getMapper(Album.class);
Album album = (Album) mapper.find(albumId); album.setTitle(title);
UnitOfWork.getCurrent().commit();
}
但是又有想到是以 repository 為單位的範例,所以我個人的理解應該是 :
我覺得應該是以 repository 操作為單位來運行,因為事務可以想成是很多業務任務所組成,他應該是接近 domain layer 那的。
而至於書中範例為什麼會是 data mapper 呢 ? 我覺得有機率是章節編排的問題,因為在談到 unitOfWork 時,還沒談到 repository ~ 哈哈。
之前我一直在思考資料庫的 transaction 在 3-Tier 到底是該在那處理,與如何處理,看起來 unitOfwork 就是答案。
資料庫的事務,要如何在 3-Tier 放在合適的位置,我之前一直在思考這件事情,而且以前寫程式碼時也很常將所有需要事務的操作,都寫在 dao 層的一個方法中,但我之前怎麼想都覺得怪怪的呢。
而 unitOfwork 有點像是將事務操作,包含資料庫的部份封裝在一起,這樣在往上想一下,它會不會是放在任務層級都可以呢 ?
這裡事實上還有個衍伸討論,一直想找時間寫 :
MonogoDB 是如何實現事務呢 ? 而它有符合 ACID 嗎 ?