2010-06-17 7 views
0

나는 InnoDB 테이블을 사용하여 MySQL 데이터베이스에 액세스하기 위해 NHibernate를 사용하고있다. 나는 InnoDB가 중첩 된 트랜잭션을 지원하지 않는다는 것을 알고 있지만, 만약 그렇다면, 훨씬 더 간단했을 것이라고 생각한다.NHibernate, MySQL, InnoDB 및 중첩 된 트랜잭션

예를 들어이 방법을 살펴보십시오. SessionManager는 스레드마다 새 세션을 엽니 다. 트랜잭션을 저장하지 않았다면, 이전 버전은 mysql이 새로운 트랜잭션을 열 때 자동으로 커밋됩니다.

이것은 단지 추악한 해결 방법입니까, 아니면 유일한 방법입니까? 그리고이 일을 더 잘 수행 할 수 있습니까?

protected override void DoCommand(ICommand command) 
{ 
    // Open session and/or transaction if necessary 
    var repoCommand = command as RepositoryCommand; 
    if (repoCommand != null) 
    { 
     foreach (Type type in repoCommand.PersistenceTypes) 
     { 
      if (!_sessions.ContainsKey(type)) 
      { 
       var session = SessionManager.GetSession(type); 
       _sessions[type] = session; 

       // Several types might share the same session, 
       // so we'll only create one transaction 
       // per session instead of per type 
       // InnoDB: Gimme nested transactions! 
       if (!_transactions.ContainsKey(session)) 
       { 
        _transactions[session] = session.BeginTransaction(); 
       } 
      } 
     } 
    } 

    base.DoCommand(command); 
} 

편집 : 프로젝트에 대한 좀 더 자세한 내용은 ..

응용 프로그램

이 NHibernate.Burrow를 사용하여 여러 데이터베이스에 연결합니다. 각 스레드는 자체 세션을 가지고 있습니다.

각 명령에는 Do 및 Undo 메서드가 있으며, 네트워크 등의 권한과 같은 prerequesites를 확인하기 위해 CanExecute 메서드를 추가 할 계획입니다. 각 명령은 단일 작업 서브 시스템 및 일부는 외부 시스템에 연결합니다.

이 클래스는 목록에있는 모든 명령을 실행하려고 시도하고 실패하면 변경 사항을 롤백합니다. RepositoryCommand는 NHibernate와 작동하는 명령입니다. 목록의 명령은 데이터를 일관된 상태로 유지하기 위해 모두 실행해야하는 여러 데이터베이스 및 외부 시스템에 연결될 수 있습니다.

+0

왜 이러한 중첩 트랜잭션이 필요합니까? 내 응용 프로그램에서는 병렬로 실행해야하는 것에 대해 하나의 기본 세션과 도우미 세션을 사용하고 있습니다. 지금까지는 아무런 문제가 없습니다. 아주 오래 실행중인 트랜잭션이 있다면 웜을 열 수 있습니다 (적어도 이것은 우리를위한 것입니다) – bernhardrusch

답변

0

트랜잭션은 수명이 짧은 개체 여야합니다. NHibernate는 중첩 된 트랜잭션을 지원하지 않으므로 도움이되지 않습니다.

거래를 처리하는 방식을 재고해야합니다. 당신은 Unit of Work 패턴에 대해 읽어 보시기 바랍니다.