[英]C# Shared Transactions and NHibernate using IRepository
我正在考慮使用NHibernate實現IRepository模式,但我有一個問題,就是我無法回答搜索網絡問題。
假設我有3個存儲庫,PersonRepository,PersonAddressRepository和PersonAccountRepository。 現在,假定業務邏輯規定存在一個調用PersonRepository.Deactivate(),PersonAddressRepository.Deactivate()和PersonAccountRepository.Deactivate()的“停用Person”過程。
我希望能夠做一些類似的事情。
using (ITransaction transaction = session.BeginTransaction()) {
session.Update(Person);
session.Update(PersonAddress);
session.Update(PersonAccount);
}
因此,如果這些更新中的任何一個失敗,整個過程將在數據庫中回滾。 現在,我對NHibernate的了解是,您只能為每個對象創建一個Session。
var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly(typeof(Person).Assembly);
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
using (ISession session = sessionFactory.OpenSession()) {
using (ITransaction transaction = session.BeginTransaction()) {
session.Save(Person);
}
這是正確的還是我弄錯了? 關於多表更新和關於NHibernate的事務的最佳實踐是什么?
提前致謝。
您不應在存儲庫或其他“波紋管”中創建事務。 事務由應用程序邏輯定義。 這是我在事務處理中看到的最常見的錯誤之一。
我寫了一個交易服務來管理交易:
using (TransactionService.CreateTransactionScope())
{
repositoryA.DoX();
repositoryB.DoY();
TransactionService.Commit();
}
存儲庫正在通過服務從開放事務中獲取會話:
TransactionService.Session.CreateQuery("...");
根據您的環境,您需要使其更加復雜。 例如,會話可能對業務邏輯不可見,應將其放置到另一個接口等上。
我以為NHibernate可以理解System.Transactions.TransactionScope類。 你為什么不使用它?
您可以做的一件事-這就是我現在的做法-將應該用於存儲庫實例的ISession實例傳遞給它。
將來,我將要做的是:
我有一個UnitOfWork
類,該類非常通用,是NHibernate的ISession
對象的包裝。 此UnitOfWork類不包含“應用程序”或特定於域的方法
在使用NHibernate(和我的UnitOfWork包裝器)的項目中,我將在UnitOfWork
類上創建一組擴展方法,如下所示:
public static class UnitOfWorkExtension` { public static IPersonRepository GetPersonRepository( this UnitOfWork uow) { return new PersonRepository(uow); } public static IAccountRepository GetAccountRepository( this UnitofWork uow ) { return new AccountRepository(uow); } }
然后,這將允許我執行此操作,例如:
using( var uow = unitOfWorkFactory.CreateUnitOfWork() )
{
var person = uow.GetPersonRepository().GetPerson (1);
var accounts = uow.GetAccountRepository().GetAccountsForPerson(person);
}
但是,看看您的示例,我想知道您是否應該為“ PersonAddress”和“ PersonAccount”提供存儲庫。 以我的拙見,在您的示例中, Person
是一個“聚合根”,它由一個PersonAddress
和一個PersonAccount
組成,並且應該有一個PersonRepository
處理該Person的聚合根(包括PersonAddress和PersonAccount對象-實際上,它們不是實體但重視對象(如我所見)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.