2011-02-08 4 views
5

트랜잭션 Scope.Eg에서 Nhibernate 및 ADO.Net 작업을 사용할 때 다음 예외가 발생합니다. Nhibernate 2.1에서는 괜찮 았으나 이제 3.0으로 업그레이드되어 오류가 발생합니다. 이 같은 주변 트랜잭션을 역할을하기 때문에 만약 내가 잘못 외부 트랜잭션이 나를 completes.correct 전에TransactionScope에서 Nhibernate 오류 - DTC 트랜잭션 준비 단계 실패 - Nhibernate 3.0으로 업그레이드

using (var scope = new TransactionScope(TransactionScopeOption.Required)) 
{ 
     GetmemberId(); --> NHibernate Call 
     Update(); ADO Call OracleDB 
} 

은, NHibernate에 곧 트랜잭션을 처리하려고 좀 도와 때문에 모든 솔루션이 있습니까,하지만 외부 NHibernate에 전화를 이동할 때 TransactionScope 모두 잘 작동합니다. 내가 준 예는 샘플 하나, 광산, 더 복잡한 일을 포함 내가 TransactionScope에 내부 전화와 스피가 점점 오류를 모두 유지해야하기 때문에

ERROR, 다음과 같은 13 NHibernate.Impl.AbstractSessionImpl입니다 - DTC 트랜잭션을 prepre 단계가 실패했습니다. System.ObjectDisposedException : 처리 된 개체에 액세스 할 수 없습니다. 개체 이름 : '거래'. System.Transactions.TransactionScope.PushScope에서 System.Transactions.TransactionScope.SetCurrent에서 System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) (거래 newCurrent)() System.Transactions.TransactionScope.Initialize에서
(트랜잭션에서 System.Transactions.TransactionScope..ctor에서 transactionToUse, 타임 스팬 scopeTimeout 부울 interopModeSpecified) NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (preparingEnlistment preparingEnlistment에서 (트랜잭션 transactionToUse)) 2011-02- 08 13 : 41 : 46,033 오류 13 NHibernate.Impl.AbstractSessionImpl - DTC 트랜잭션 준비 단계 실패 System.ObjectDisposedException : 폐기 된 개체에 액세스 할 수 없습니다. 개체 이름 : '거래'. System.Transactions.TransactionScope.PushScope에서 System.Transactions.TransactionScope.SetCurrent에서 System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) (거래 newCurrent)() System.Transactions.TransactionScope.Initialize에서
(트랜잭션에서 NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (preparingEnlistment preparingEnlistment에서 System.Transactions.TransactionScope..ctor에서 transactionToUse, 타임 스팬 scopeTimeout 부울 interopModeSpecified) (트랜잭션 transactionToUse))

012,351,

답변

6

Configuration.SetProperty(Environment.TransactionStrategy,"NHibernate.Transaction.AdoNetTransactionFactory")

시도하거나 NHibernate에 설정에서

<property name="transaction.factory_class"> 
NHibernate.Transaction.AdoNetTransactionFactory 
</property> 
그것은 나를 위해 일한

=)

+0

감사합니다. 그것은 나를 위해 일했습니다! – Saxophonist

1

우리는이 같은 오류로 실행하고,이 방식으로 인해 발생 된 우리는 NHibernate와 웹 API에서 세션과 트랜잭션을 사용했습니다.

은 세션 당 요청을 사용해야합니다. (이것은 웹 요청이거나 NServiceBus 핸들러의 실행 일 수 있습니다.) 요청이 시작되면 세션을 열고 트랜잭션을 시작해야합니다.

우리는 그렇게하지 않았습니다. 우리 저장소에서는 모든 데이터베이스 요청에 대해 새로운 세션과 트랜잭션을 만들었습니다. 즉, 요청에 대해 단일 세션/트랜잭션을 갖는 것보다 많은 것을 갖게되었습니다.

버그의 근본 원인은 우리가 한 세션에서 엔터티 (도메인 모델 개체)를로드하고 수정 한 다음 다른 세션을 사용하여 저장했다는 것입니다. NHibernate가 업데이트 호출을 실행했을 때, 로딩 세션/트랜잭션은 이미 커밋되고 플러시되고 닫혔다.

해결책은 우리의 세션/트랜잭션 생성을 리포지토리에서 컨트롤러 계층 (REST 호출을 위해 HttpModule을 사용하거나 의존성 삽입을 사용하여 aspect 지향 프로그래밍을 사용하여 행할 수 있음)까지 끌어내는 것이 었습니다. 이 세션/트랜잭션은 REST 호출 또는 NServiceBus 처리기 실행의 수명 동안 존재하며 해당 호출 중 모든 데이터베이스 액세스에 사용됩니다. 통화가 끝나면 해당 통화가 커밋되거나 롤백됩니다.

위에서 주어진 설정 속성을 설정하면 DTC가 꺼지고 Hibernate 트랜잭션을 수행하는 이전 방법으로 되돌아갑니다. Web Api를 여러 인스턴스로 확장 할 필요가 없다면 문제가 해결 될 수도 있지만 그렇게하면 문제가 발생할 것입니다.

관련 문제