2011-02-17 6 views
0

NHibernate를 사용하여 IRepository 패턴을 구현하고 있는데 그물 검색에 응답 할 수 없다는 질문이 있습니다.C# 공유 트랜잭션 및 IRepository를 사용하는 NHibernate

3 개의 리포지토리, PersonRepository, PersonAddressRepository 및 PersonAccountRepository가 있다고 가정합니다. 이제 비즈니스 로직에서 PersonRepository.Deactivate(), PersonAddressRepository.Deactivate() 및 PersonAccountRepository.Deactivate()를 호출하는 "Deactivate Person"프로세스가 있다고 가정합니다.

나는의 라인을 따라 뭔가를 할 수 있어야합니다 ..

using (ITransaction transaction = session.BeginTransaction()) { 
    session.Update(Person); 
    session.Update(PersonAddress); 
    session.Update(PersonAccount); 
} 

해당 업데이트의 전체 프로세스가 다시 데이터베이스 내에서 롤 것을 실패하는 경우가 그래서. 지금 NHibernate에 대한 나의 이해는 객체 당 세션만을 생성 할 수 있다는 것을 의미한다 ..

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와 관련하여 다중 테이블 업데이트 및 트랜잭션에 관한 트랜잭션의 모범 사례는 무엇입니까?

미리 감사드립니다.

답변

5

리포지토리 또는 다른 곳에서 트랜잭션을 생성해서는 안됩니다. 트랜잭션은 응용 프로그램 논리에 의해 정의됩니다. 이것은 트랜잭션 처리에서 볼 수있는 가장 일반적인 실수 중 하나입니다.

내가 트랜잭션을 관리하는 트랜잭션 서비스를 썼다 :

using (TransactionService.CreateTransactionScope()) 
{ 
    repositoryA.DoX(); 
    repositoryB.DoY(); 
    TransactionService.Commit(); 
} 
저장소는 서비스의 오픈 트랜잭션 세션을 받고있다

:

TransactionService.Session.CreateQuery("..."); 

사용자 환경에 따라 필요 좀 더 복잡하게 만드십시오. 예를 들어, 세션이 비즈니스 로직에 보이지 않을 수도 있고 다른 인터페이스 등에 놓여 야합니다.

+0

안녕하세요, 답변을 주셔서 감사합니다, 내 후속 질문입니다,이 TransactionService 효과적으로 하나의 다음 모든 트랜잭션 풀에 롤백됩니다 그래서 트랜잭션 풀 관리 관리 있습니까? 또는 여러 저장소에서 1 트랜잭션을 공유하는 방법이 있습니까? – David

+0

스레드 당 트랜잭션이 있습니다. 물론 다른 병렬 트랜잭션은 다른 스레드에서 계속 수행됩니다. –

0

Hibernate가 System.Transactions.TransactionScope 클래스를 이해한다고 생각했습니다. 왜 그렇게 쓰지 않았을까요?

+0

코드 예제 또는 참조 소스를 제공 할 수 있습니까? – Alex

0

당신이 할 수있는 한 가지 - 지금 당장 어떻게해야합니까? 저장소 인스턴스에 사용해야하는 ISession 인스턴스를 전달해야합니다.

내가 무엇을 할 것인지, 미래에, 이것이다 :

  • 나는 매우 일반적인이며, NHibernate에의 ISession 객체의 래퍼 인 UnitOfWork 클래스를 가지고있다.이 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); 
} 

을, 나는 wheth 궁금하네요 'PersonAddress'및 'PersonAccount'에 대한 저장소가 있어야합니다. 겸손한 견해로는 Person은 예에서 PersonAddressPersonAccount으로 구성된 '집계 루트'이며 Person 집계 루트 (PersonAddress 및 PersonAccount 개체 포함)를 처리하는 PersonRepository이 있어야합니다. 실제로는 엔티티가 아니라 값 객체 (내가 본 것처럼)).

관련 문제