Martin Fowler定义的存储库应该像内存域对象集合一样工作。这允许应用程序(理论上)不知道持久性机制。
所以在正常情况下,你会有这样的事情:
public void MyBusinessLogicMethod () {
...
IRepository<Customer> repository = myIocContainer.Resolve<IRepository<Customer>>();
repository.Add(customer);
}
但是,如果您希望执行一系列插入/更新,并且希望在其中任何一个失败时回滚机制,则需要某种UnitOfWork实现:
public void MyBusinessLogicMethod () {
...
using (IUnitOfWork uow = new UnitOfWork()){
IRepository<Customer> customerRepo = myIocContainer.Resolve<IRepository<Customer>>(uow);
customerRepo.Add(customer);
IRepository<Order> orderRepo = myIocContainer.Resolve<IRepository<Order>>(uow);
orderRepo.Add(order);
IRepository<Invoice> invoiceRepo = myIocContainer.Resolve<IRepository<Invoice>>(uow);
invoiceRepo.Update(invoice);
uow.Save();
}
}
但是,如果您有一个奇怪的要求,即您的客户存储库是针对SqlServer数据库,针对MySql数据库的订单存储库和针对PostgreSQL数据库的发票存储库,那么您将如何处理每个数据库会话的事务?
现在这肯定是一个人为的例子,但我遇到的每个Repository实现似乎都知道它确实是一个特定的数据库并且正在使用ORM。
想象一下另一个场景,你有2个存储库,其中一个存储库是数据库而另一个是调用Web服务。存储库的重点在于应用程序不应该关心你要使用的是什么数据源,但是如果没有应用程序在某种程度上知道,我不会看到如何解释这些情况“我是这样的转到数据源x所以我们最好区别对待它。“
是否存在解决此问题的模式或实现?在我看来,如果您在整个应用程序中使用Database x和ORM y,那么存储库工作非常出色,但如果由于技术债务而导致存储库偏离,那么存储库的好处就会大大减少。
答案 0 :(得分:0)
在您的UnitOfWork中,如建议的那样,您应该使用 TransactionScope 事务。 在您的情况下,它会升级到MSDTC并确保在提交或以其他方式回滚之前正确执行所有登记的操作。