3

Castle NHibernate Facility을 AutoTx Facility와 함께 사용하려고합니다. 테스트로서 트랜잭션이 롤백되는지 확인하기 위해 서비스 도중에 예외가 발생합니다. 그러나 데이터는 여전히 데이터베이스에 유지됩니다.Castle AutoTx Facility와 NHibernate Facility를 사용한 트랜잭션

내 서비스 인터페이스, IActivityService TransactionAttribute를 사용하여 : CreateActivity

public interface IActivityService 
{ 
    [Transaction] 
    Activity CreateActivity(Activity activity); 
} 

구현합니다. 나는 롤백 AddActivity에서 추가 데이터를 예상하고, 여기에 예외를 발생 해요 : AddActivity

public virtual Activity CreateActivity(Activity activity) 
{ 
    activityDAO.AddActivity(activity); 
    throw new Exception("This should rollback the transaction"); 
    return activity; 
} 

구현. SessionManager은 주사 된 ISessionManager입니다.

public void AddActivity(Activity activity) 
{ 
    using (ISession session = SessionManager.OpenSession()) 
    { 
     session.Save(activity); 
    } 
} 

마지막으로 윈저 컨테이너를 구성하는 방법은 다음과 같습니다. 구성은 매우 간단 보였다

container = new WindsorContainer().Install(FromAssembly.This()); 

// set up ISessionManager injection for DAOs 
container 
    .AddFacility<AutoTxFacility>() 
    .Register(Component 
     .For<INHibernateInstaller>() 
     .ImplementedBy<NHibernateInstaller>() 
     .LifeStyle.Singleton) 
    .AddFacility<NHibernateFacility>(f => 
     f.DefaultLifeStyle = DefaultSessionLifeStyleOption.SessionPerWebRequest); 

,하지만 난 내가 부족 알아낼 수 없습니다 내 능통 자 NHibernate 구성에서 교체와 NHibernateInstaller는 바로 the guide에서입니다. 어떤 도움을 주셔서 감사합니다.

답변

1

서비스 구현 클래스에 대한 클래스 선언 코드를 표시하지 않았으므로 이미 수행했을 수도 있지만 선언적 트랜잭션이 필요하면 [Transactional] 속성을 사용하여 트랜잭션 클래스에 주석을 추가해야합니다.

[Transactional]  
public class ActivityServiceImpl { 

    [Transaction] 
    public Activity CreateActivity(Activity activity) { 
     // ... implementation here 
    } 
} 

구현 클래스에 [Transactional] 특성을 포함하지 않으면 AutoTx 기능은 클래스의 래퍼를 만들지 않습니다.

인터페이스 정의가 아닌 구현 방법에 [Transaction] 속성을 사용하는 경향이 있습니다. 그것은 인터페이스 메소드 선언에 주석을 달고 있는지 모른다.

한번 더 시도해야 할 수도 있습니다. 컨테이너를 구성 할 때 먼저 설치하고 AutoTx 기능을 추가합니다. 설치 프로그램을 호출하기 전에 먼저 기능을 추가해야한다고 생각합니다.

+1

아, 네가 두 번 맞았다. 고마워! 설치 프로그램을 호출하기 전에 설비를 추가해야했고'[Transaction]'을 구현해야했습니다. 단지 부수적 인,'[Transactional]'속성은 더 이상 사용되지 않습니다 (Castle.Services.Transaction.3.0.202.2202를 실행 중입니다). 그것은 그것없이 잘 작동합니다. – Will

1

처음에는 세션 관리자와 Activity Service간에 직접적인 종속성이 있어야합니다. 세션 관리자는 Activity Service에 주입되어야한다. 이 경우에만 시설이 NHibernate 트랜잭션에 영향을 줄 수 있습니다.

 
    [Transactional] 
    public class ActionService : IActionService 
    { 
     private ISessionManager _sessionManager; 

     [Transaction] 
     public void AddActivity(Activity activity) 
     { 
      using (ISession session = _sessionManager.OpenSession()) 
      { 
       using (ITransaction tran = session.BeginTransaction()) 
       { 
         session.Save(activity); 
        tran.Commit(); 
       } 
      }  
     } 
     public ActionService(ISessionManager sessionManager) 
    { 
      _sessionManager = sessionManager;  
     } 
    } 
    _container.Register(Component.For<IActionService>() 
      .ImplementedBy<ActionService>.LifestylePerWebRequest()); 

또한 세션 관리자, 서버, DAO 및 기타 종속 개체에 대해 동일한 라이프 스타일을 사용하고 있는지 확인하십시오.

+0

답장을 보내 주셔서 감사합니다. 귀하의 견본에서는 거래를 수동으로 관리하고있는 것으로 나타났습니다. AutoTx 기능을 사용하면 안됩니다. – Will

+0

성 소스를 한 번 더 확인했는데 NHibernate 트랜잭션 관리 통합이 표시되지 않습니다. 문서는 "이 시설은 일반적으로 ITransactionManager의 구현을 필요로하기 때문에 다른 시설과 함께 작동합니다. 현재 ActiveRecord Integration Facility는 NHibernate 설비와 iBatis.Net 설비가 ITransactionManager를 구현합니다." 하지만 NHibernate 시설은 어떤 것을 구현하지 못한다. 컨테이너에 DefaultTransactionManager만을 등록한다. nhprof 유틸리티를 사용하여이를 확인할 수 있습니다 : "암시 적 트랜잭션 사용은 권장하지 않습니다"라고 말할 것입니다. –

관련 문제