1.前言
疑問? 怎樣保存業務的單一原子性?在學習數據庫事務的時候,一直有個疑問:數據庫可以對一系列操作在出現異常的時候進行回滾操作,從而保證了事務的單一原子性,那么在業務操作的時候(業務層操作)是否也可以保證業務的單一原子性呢?恰好最近在研究領域驅動模型的設計的時候,提到了Unit of Work 工作單元模式,恰好解決了我的疑問。
2. 工作單元模式
工作單元模式:用來維護一個已經被業務事務修改(CURD操作)的業務對象列表。工作單元模式負責協調這些修改的持久化工作以及所有標記的並發問題。采用工作單元模式帶來的好處是能夠保證數據的完整性。如果在持久化一系列業務對象的過程中出現問題,則將所有的修改回滾,以保證數據始終處於有效狀態。簡單來說,工作單元模式就是把業務對象的持久化由工作單元實現類進行統一管理。而不想之前那樣,分布在每個具體的倉儲類中,這樣就可以達到一系列業務對象的統一管理,不至於在每個業務對象中出現統一的提交和回滾業務邏輯,實現代碼最大化重用。
簡單概括就是:對某個業務操作,比如銀行的進出賬的業務對象(進賬對象,出賬對象)進行統一管理,使它們不需要在自己的repository中提交(commit),放在工作單元中做持久化工作。
3.工作單元組成部分
3.1 IUnitofWork接口,定義持久化工作的方法,復雜維護變化的對象列表,並最后Commit,依次遍歷變化的列表,並持久化,這就是Commit的事情。
public interface IUnitOfWork { void RegisterAdded(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository); void RegisterChangeded(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository);
//刪除操作 void RegisterRemoved(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository); void Commit(); //提交操作 }
3.2 IUnitOfWorkRepository,負責持久化對象。
//持久化工作
public interface IUnitOfWorkRepository { void PersistNewItem(EntityBase entityBase); void PersistUpdatedItem(EntityBase entityBase); void PersistDeletedItem(EntityBase entityBase); }
3.UnitOfWork 繼承IUnitofWork接口,工作單元具體實現。
public class UnitOfWork:IUnitOfWork { #region Fields private Dictionary<EntityBase, IUnitOfWorkRepository> addedEntities; private Dictionary<EntityBase, IUnitOfWorkRepository> changededEntities; private Dictionary<EntityBase, IUnitOfWorkRepository> removedEntities; #endregion #region Constructor public UnitOfWork() { addedEntities=new Dictionary<EntityBase, IUnitOfWorkRepository>(); changededEntities=new Dictionary<EntityBase, IUnitOfWorkRepository>(); removedEntities=new Dictionary<EntityBase, IUnitOfWorkRepository>(); } #endregion #region Implement IUnitOfWork public void RegisterAdded(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository) { this.addedEntities.Add(entityBase,unitOfWorkRepository); } public void RegisterChangeded(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository) { this.changededEntities.Add(entityBase,unitOfWorkRepository); } public void RegisterRemoved(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository) { this.removedEntities.Add(entityBase,unitOfWorkRepository); }
//提交操作,在這里保存了業務的原子性操作 public void Commit() { using (var trans=new TransactionScope()) { foreach (var entity in addedEntities.Keys) { addedEntities[entity].PersistNewItem(entity); // } foreach (var entity in changededEntities.Keys) { changededEntities[entity].PersistUpdatedItem(entity); } foreach (var entity in removedEntities.Keys) { removedEntities[entity].PersistDeletedItem(entity); } trans.Complete(); //提交 } } #endregion }
解析:TransactionScope 對象,msdn解釋:使代碼塊事務。 此類不能被繼承,也就是提供事務操作。TransactionScope是基於當前線程的,在當前線程中(代碼塊中的多個數據庫操作應該在一個線程中執行,避免在多線程或是異步操作),調用Transaction.Current方法可以看到當前事務的信息.通俗易懂的講就是在用TransactionScope 包裹的代碼中統一對數據庫操作進行事務管理,當執行完代碼塊的時候必須顯示調用其commit方法提交事務,如果中途發送了異常就會自動回滾操作,原理和數據庫的事務操作是一樣的.
3.4 ****Repository 實現具體的IUnitOfWorkRepository接口操作,****Service服務類使用****Repository進行對象的持久化操作.
業務對象倉儲實現IUnitOfWorkRepository接口的方法,PersistNewItem、PersistUpdatedItem、PersistDeletedItem 三個方法的具體內容