2016-08-03 1 views
0

웹 API/MVC 응용 프로그램의 세션을 관리하기 위해 ninject를 사용하고 있습니다. 코드는 다음과 같습니다 :Ninject 3.2 OnDeactivation 웹 API 실행 안 함

Bind<ISession>().ToMethod(c => c.Kernel.Get<ISessionFactory>().OpenSession()) 
      .InRequestScope() 
      .OnActivation(s => s.BeginTransaction()) 
      .OnDeactivation((s) => 
      { 
       try 
       { 
        s.Transaction.Commit(); 
       } 
       catch (Exception e) 
       { 
        s.Transaction.Rollback(); 
       } 

       s.Close(); 
       s.Dispose(); 
      }); 
    } 

OnActivation 코드가 올바르게 호출됩니다. 세션이 삽입되면 트랜잭션이 시작됩니다. 그러나 요청이 완료되면 ondeactivation은 호출되지 않습니다. 따라서 데이터베이스에서 항목을 쿼리 할 수는 있지만 변경 사항을 커밋 할 수는 없습니다 (다른 곳에서 트랜잭션을 커밋하지 않은 경우).

나는 왜 OnDeactivation이 호출되지 않는지 잘 모르겠다. 나의 설치 프로그램에서 뭔가 빠졌는가? OnDeactivation항상가 호출되기 때문에 OnDeactivation 동안 Commit를 호출

답변

0

는 예외가 비즈니스 계층 내에서 발생되는 경우에도, 정말 나쁜 생각입니다. 오류가 발생하면 트랜잭션을 커밋하지 않으려 고합니다.

다른 수준의 커밋을 고려해야합니다. This q/a에서 이에 대해 자세히 이야기하고이 문제를 해결하는 방법을 보여줍니다.

코드가 지나치게 길기 때문입니다. Dispose으로 전화하면 Close에 전화 할 필요가 없으며 커밋되지 않은 트랜잭션에서 Dispose을 호출하면 트랜잭션이 자동으로 롤백됩니다. 플러그를 뽑아도 데이터베이스가 커밋되지 않은 트랜잭션을 자동으로 롤백합니다. 즉, 당신은 쉽게 다음에 코드를 단순화 할 수 있습니다 : 당신이 설명 hereOnePerRequestHttpModule의 사용을 할 때 당신은 심지어 Dispose을 제거 할 수 있습니다

.OnDeactivation((s) => 
{ 
    try 
    { 
     s.Transaction.Commit(); 
    } 
    finally 
    { 
     s.Dispose(); 
    } 
}); 

. 이렇게하면 코드가 더 줄어 듭니다.

.OnDeactivation(s => s.Transaction.Commit()); 

다시 말해서 OnDeactivation은 커밋하기에 절대적으로 잘못된 장소입니다.

+0

- 커밋을 다른 곳으로 옮길 것입니다. 내 문제는 ondeactivation이 (항상) 호출되지 않았다는 것입니다 - 그 이유는 무엇입니까? – Bonnotbh

+1

@Bonnotbh OnDeactivation 및 폐기는 일반적으로 Ninject에서 비결정입니다. Ninject는 쓰레기를 GC로 수집 한 후 정리합니다. 데이터베이스 연결에는이 기능을 사용할 수없는 경우가 종종 있습니다. – Steven