2

좋습니다. 여기에 시나리오가 있습니다. 정기적으로 백그라운드 스레드를 생성하여 일부 작업을 수행하는 ASP.NET 사이트가 있습니다. 스레드의 실행은 IJob 목록을 반복하고 각각에 대해 Execute()를 호출하는 JobRunner로 구성됩니다. JobRunner와 각 IJob은 NInject에 의해 생성됩니다. IJobs의 한 쌍은 IRepository <ModelType>에 대한 의존성이 있습니다. IRepository의 구현은 NHibernate를 사용하기 때문에 ISession에 대한 생성자 인수가 있습니다. 지금까지는 NInject가 각 요청 (InRequestScope) 범위의 ISessionFactory에서 ISession을 반환하도록했습니다.NInject와 함께 스폰 된 스레드에서 NHibernate Session을 범위 지정

다음과 같은 문제가 있습니다. 다양한 IJob이 IRepository에 저장하는 것을 포함하여 처리 할 때 ISession.Flush()가 호출되지 않기 때문에 데이터가 지속되지 않습니다. 각 IJob은 사용하는 IRepository의 구현에 대해 아무것도 모릅니다. 마찬가지로, JobRunner는 실행중인 IJob의 구현에 대해 아무것도 모릅니다. 나머지 웹 응용 프로그램에서는 ISession.Flush()가 Application_EndRequest에서 호출되기 때문에 정상적으로 작동합니다.

나는 모든 IJobs 처리가 끝났을 때 Flush()를 호출 할 수 있도록 Idession을 생성자 인자로 넣어 봤지만 IJobs (session.GetHashCode ()는 JobRunner에 대해 다른 값을 반환하지만 모든 IJob에 대해서는 동일합니다. HttpContext가있을 경우 NInject를 범위 ISession에 구성하고, 그렇지 않으면 CurrentThread를 사용합니다. JobRunner가 별도의 스레드에 있기 때문에 CurrentThread 범위의 ISession을 얻게 될 것이고 모든 IJob은 JobRunner와 같은 스레드에서 실행되기 때문에 모두 동일한 Session을 가져야한다고 생각했지만 그렇지 않습니다.

내 질문은 내가하는 일을하는 더 좋은 방법이 있습니까? 누구도 같은 스레드에서 여러 요청에 대해 다른 Session 인스턴스를 얻는 이유를 알고 있습니까?

이제는 해결 방법이 있습니다. session.Flush()를 NHibernateRepository.Save() 메서드의 마지막 줄에 넣었지만 그 점에 만족하지 않습니다.

답변

1

잘 솔루션을 찾았습니다. 내 JobRunner 객체가 Global.asax의 Application_Start 메소드에서 인스턴스화되었으므로 백그라운드 스레드 ID 대신 해당 스레드 ID가 보유되었습니다.

형식을 사용하고 NInject를 사용하여 인스턴스를 만드는 래퍼 클래스를 만들었으며 백그라운드 스레드가 처리를 시작할 때마다 래퍼 클래스를 사용하여 JobRunner 인스턴스를 가져 왔습니다. 그게 내가 IRepository 같은 세션을 얻을 수 있도록 적절한 스레드에서 만듭니다 그래서 모든 IJobs가 완료된 후 session.Flush()를 호출 할 수 있습니다.

더 좋은 해결책이있을 수도 있지만 그때까지는 효과가 있습니다.

관련 문제