2012-11-02 4 views
1

내 작업 단위 (UOW)가 아키텍처에 잘못 설정된 것 같습니다. 여기에 내가 현재 가지고있는 것 (주문을 보여주기 위해 들여 쓰기)이 있습니다 : 여기에 나는 NHibernate를 사용하여 crud를 수행하기위한 다양한 서비스를 호출합니다. 내가으로 실행하고NHibernate의 작업 단위 및 요청 당 세션

 UnitOfWork.Commit() 
    Transaction.Commit() // This is my sessions transaction from the begin above 

을 다음 HttpRequest에이 끝나면

 using (var transaction = unitOfWork.Session.BeginTransaction()) 
     { 
      try 
      { 
       // These are just generics 
       ret = (Key)unitOfWork.Session.Save(entity); 
       transaction.Commit(); 
       rb.unitOfWork.Session.Clear(); 
      } 
      catch 
      { 
       transaction.Rollback(); 
       rb.unitOfWork.Session.Clear(); 
       rb.unitOfWork.DiscardSession(); 
       throw; 
      } 
     } 

, 나는 이러한 단계를 수행 : 나는 (저장/업데이트) 데이터베이스를 변경하려는 경우,이 코드를 호출 대량 배치 프로세스를 롤백 할 수있는 문제 위에서 볼 수 있듯이 CRUD 계층에서 트랜잭션을 커밋하기 때문에 트랜잭션이 더 이상 활성화되지 않고 UnitOfWork에서 롤백을 시도 할 때 이미 커밋 된 트랜잭션 때문에 아무것도 수행되지 않습니다. 내 CRUD 계층에서 내 코드를 커밋하는 이유는 너무 오래 데이터베이스를 잠그지 않고 최대한 빨리 내 데이터를 유지할 수 있기 때문입니다.

위와 같은 상황에서 취할 수있는 최선의 조치는 무엇입니까? 일괄 처리 작업을 수행하지 않고 작업이 끝나면 커밋을 처리하는 특별한 CRUD 작업을 수행합니까, 아니면 UnitOfWork 및 Session Per Request에 내 논리가 결함이 있습니까? 어떤 제안?

답변

8

요청 당 세션 패턴이 널리 사용되는 이유와 작업 단위를 미세 관리하는 데서 생기는 문제를 발견했습니다.

일반적으로 각 웹 요청에서 해당 요청 내에서 수행해야하는 모든 작업은 하나의 작업 단위로 간주 될 수 있으므로 하나의 작업 단위 만 있고 그 중 하나의 NHibernate 세션 만 열려야하는 이유가 있습니다 웹 요청.

또한, 당신이 질문에이 문장으로 인해 NHibernate가 작동하는 방식에 대해 다소 혼란 스러울 수도 있습니다. "내 CRUD 계층에서 내 코드를 커밋하는 이유는 가능한 한 빨리 데이터를 유지할 수 있기 때문입니다. 너무 오래 데이터베이스를 잠그지 않고. "

NHibernate는 데이터베이스에 어떤 잠금도 일으키지 않을 것입니다. ISession.Flush() 또는 ITransaction.Commit()을 호출하지 않는 한 ISession.Save (엔터티)를 호출 할 때마다 데이터베이스에 쓰여지는 것이 아니라 삽입 될 항목의 큐에 추가됩니다 현재 트랜잭션이 웹 요청의 끝에서 커밋 될 때 데이터베이스에서 업데이트됩니다. 물론

void Application_BeginRequest() 
{ 
    // Start your unit of work, open a session and begin a transaction 
} 

// Do all of your work (Read, insert, update, delete) 

void Application_EndRequest() 
{ 
    try 
    { 
     // UnitOfWork.Current.Transaction.Commit(); 
    } 
    catch(Exception e) 
    { 
     // UnitOfWork.Current.Transaction.Rollback(); 
    } 
} 

이 같은 일을하는 방법에는 여러 가지가 있지만, 이것은 --only 하나 개의 세션 요청 패턴 당 세션의 기본입니다 :

그래서 요청에 따라 세션이과 같이 설정해야한다 전체 웹 요청.

+0

가장 간단한 설명 지금까지 발견했습니다! – Joel