우리는 Castle 자동 트랜잭션과 NHibernateIntegration 기능을 위해 성 기능을 프로젝트에서 사용하고 있습니다.Castle.Facilities.AutoTx 오류와의 트랜잭션 문제 "두 개의 열린 세션으로 콜렉션을 연결하려고 시도가 잘못되었습니다."
초기 설정은 메소드 당 트랜잭션 이었지만 전체 작업 단위를 롤백하는 데 문제가있었습니다. 모두 잘 작동했다.
<component id="SessionModule"
service="BCS.Modules.ISessionModule, BCS.Modules"
type="BCS.Modules.SessionModule, BCS.Impl"
isTransactional="true">
<transaction>
<method name="GetCurrentDate" />
<method name="GetCurrentDateAndTime" />
</transaction>
</component>
그런 다음 우리는 전체 요청에서 롤백 작업에 문제가 시작, 그래서 우리는 예에 의해 아버지의 트랜잭션 그룹에 비즈니스 트랜잭션 당 모든 단일 트랜잭션을 결정 : 방법 당이 작은 트랜잭션에 대한 우리의 성 구성은 다음과 같습니다
namespace BCS.BusinessRules {
[Transactional]
public class TransactionModule : ITransactionModule {
[Transaction(TransactionMode.Requires, IsolationMode.ReadUncommitted, Distributed = false)]
public Dictionary<String, double> CalculateGoalSetting(Member member, WorkflowContext contextSetting) {
// Calling a lot of child transactional methods for this unit of work
}
[Transaction(TransactionMode.Requires, IsolationMode.ReadUncommitted, Distributed = false)]
public MembershipOperationResult SelfEnrollment(Member member) {
// Same here, Another unit of work
}
}
}
이러한 작업 단위 (unit)는 웹 애플리케이션에서 요청 당 하나씩 호출됩니다. 그러나 그 후에는 과 같은 문제가 발생하기 시작합니다. 두 개의 열린 세션이있는 컬렉션을 연결하려고 시도했습니다., 제한 시간이 만료되었습니다. 작업이 완료되기 전에 시간 초과 기간이 경과되었거나 서버가 응답하지 않습니다.와 몇 번 죽은 잠금
가장 흔한 오류입니다 : '/'응용 프로그램에
서버 오류가 발생했습니다. 두 개의 열린 세션을 가진 컬렉션을 연결할 때 잘못된 시도가 발생했습니다. 설명 : 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 오류 및 코드에서 시작된 위치에 대한 자세한 정보는 스택 추적을 검토하십시오.
예외 정보 : NHibernate.HibernateException : 처리되지 않은 예외가 현재 웹 요청을 실행하는 동안 생성 된 두 개의 열린 세션
소스 오류와 함께 컬렉션을 연결하는 불법 시도. 예외의 출처와 위치에 관한 정보는 아래의 예외 스택 추적을 사용하여 식별 할 수 있습니다.
스택 추적 :
[HibernateException: Illegal attempt to associate a collection with two open sessions]
NHibernate.Collection.AbstractPersistentCollection.SetCurrentSession(ISessionImplementor session) +242
NHibernate.Event.Default.OnUpdateVisitor.ProcessCollection(Object collection, CollectionType type) +177
NHibernate.Event.Default.AbstractVisitor.ProcessEntityPropertyValues(Object[] values, IType[] types) +83
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformUpdate(SaveOrUpdateEvent event, Object entity, IEntityPersister persister) +632
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event) +101
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) +365
NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event) +394
NHibernate.Impl.SessionImpl.SaveOrUpdate(String entityName, Object obj) +392
NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything) +578
NHibernate.Event.Default.AbstractFlushingEventListener.CascadeOnFlush(IEventSource session, IEntityPersister persister, Object key, Object anything) +157
NHibernate.Event.Default.AbstractFlushingEventListener.PrepareEntityFlushes(IEventSource session) +364
NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) +225
NHibernate.Event.Default.DefaultAutoFlushEventListener.OnAutoFlush(AutoFlushEvent event) +83
NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet`1 querySpaces) +474
NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) +782
NHibernate.Impl.CriteriaImpl.List(IList results) +63
NHibernate.Impl.CriteriaImpl.UniqueResult() +69
BCS.Modules.Behavior.BehaviorElementDataAccess.GetByName(String name) in c:\Projects\dps\bcs\branches\bcs31\BCS.Impl\Modules\Behavior\BehaviorElementDataAccess.cs:41
BCS.Modules.Behavior.BehaviorManagerModule.FindBehaviorElementByName(String behaviorName) in c:\Projects\dps\bcs\branches\bcs31\BCS.Impl\Modules\Behavior\BehaviorManagerModule.cs:191
Castle.Proxies.Invocations.IBehaviorManagerModule_FindBehaviorElementByName.InvokeMethodOnTarget() +147
Castle.DynamicProxy.AbstractInvocation.Proceed() in e:\OSS.Code\Castle.Core\src\Castle.Core\DynamicProxy\AbstractInvocation.cs:144
Castle.Facilities.AutoTx.TransactionInterceptor.Intercept(IInvocation invocation) in c:\dev\dotnet\castle\main\Castle.Facilities.AutomaticTransactionManagement\src\Castle.Facilities.AutoTx\TransactionInterceptor.cs:92
Castle.DynamicProxy.AbstractInvocation.Proceed() in e:\OSS.Code\Castle.Core\src\Castle.Core\DynamicProxy\AbstractInvocation.cs:166
Castle.Proxies.IBehaviorManagerModuleProxy.FindBehaviorElementByName(String behaviorName) +356
KAO.Behavior.CommonBehaviorCalculations.SaveGoalActivityMinutes(Member member, JulianDate startingDate, JulianDate endingDate, JulianDate currentDate) in c:\svn\qupio21\KAO\Behavior\CommonBehaviorCalculations.cs:148
KAO.BusinessRules.TransactionModule.CalculateGoalSetting(Member member, WorkflowContext contextSetting) in c:\svn\qupio21\KAO.BusinessRules\TransactionModule.cs:111
Castle.Proxies.Invocations.ITransactionModule_CalculateGoalSetting.InvokeMethodOnTarget() +155
Castle.DynamicProxy.AbstractInvocation.Proceed() in e:\OSS.Code\Castle.Core\src\Castle.Core\DynamicProxy\AbstractInvocation.cs:144
Castle.Facilities.AutoTx.TransactionInterceptor.Intercept(IInvocation invocation) in c:\dev\dotnet\castle\main\Castle.Facilities.AutomaticTransactionManagement\src\Castle.Facilities.AutoTx\TransactionInterceptor.cs:169
Castle.DynamicProxy.AbstractInvocation.Proceed() in e:\OSS.Code\Castle.Core\src\Castle.Core\DynamicProxy\AbstractInvocation.cs:166
Castle.Proxies.ITransactionModuleProxy.CalculateGoalSetting(Member member, WorkflowContext context) +183
BCS.Web.App.Landing.Tunneling.Goals.cmdCalculate_Click(Object sender, EventArgs e) in c:\svn\qupio21\BCS.Web.App\Landing\Tunneling\Goals.aspx.cs:104
System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +155
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3707
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272
우리의 데이터 액세스 계층은 현재 오픈 세션의 NHibernate에 통합 기능을 사용하고 있습니다 :
public class BehaviorElementDataAccess : DataAccessBase<BehaviorElement, Int64>, IBehaviorElementDataAccess {
public BehaviorElementDataAccess(ISessionManager sessionManager) : base(sessionManager) { }
public T GetById<T>(long id) where T : BehaviorElement {
T ret;
using (ISession session = SessionManager.OpenSession()) {
ret = session.Load<T>(id);
session.Evict(ret);
}
return ret;
}
}
우리는 두 개의 세션이 여기에 사용하는 방법을 모른다, 하위 트랜잭션이 모두 정상적으로 작동하기 전에는 이제 동시성이 크게 감소했습니다. 캐슬 AutoTX를 사용하는 트랜잭션의 기본값은 XML 구성 파일에서만 선언 된 XML의 경우 IsolationLevel.ReadCommited이고, 반면에 코드 파일에 선언 된 트랜잭션 인 경우 IsolationLevel.ReadUncommited입니다. 따라서이 동작을 상속받은 자식 객체는 트랜잭션에 대해 동일한 최대 절전 모드 세션을 공유합니다.
Nhibernate 수준에서 데이터베이스의 격리 수준이이 영향을 받습니까? 우리는> 우리 시설의 데이터베이스에 대해이 설정을 가지고 :
<?xml version="1.0" encoding="utf-8" ?>
<castle>
<!-- Facilities -->
<facilities>
<facility id="atm" type="Castle.Facilities.AutoTx.TransactionFacility, Castle.Facilities.AutoTx">
</facility>
<facility id="nhibernate" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration">
<factory id="nhibernate.factory" alias="nh.facility.default">
<settings>
<item key="connection.provider">NHibernate.Connection.DriverConnectionProvider</item>
<item key="connection.driver_class">NHibernate.Driver.SqlClientDriver</item>
<item key="connection.connection_string_name">SQLServerConnection</item>
<item key="connection.isolation">ReadCommitted</item>
<item key="dialect">NHibernate.Dialect.MsSql2008Dialect</item>
<item key="adonet.batch_size">0</item>
<item key="use_outer_join">true</item>
<item key="query.substitutions">true 1, false 0, yes 'Y', no 'N'</item>
<item key="show_sql">true</item>
<item key="command_timeout">600</item>
<item key="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</item>
<item key="cache.use_minimal_puts">true</item>
</settings>
<assemblies>
<assembly>BCS.Impl</assembly>
</assemblies>
<listeners>
<listener type="BCS.NHibernate.Types.ActivitySaveUpdateListener, BCS.Impl" event="Save"/>
<listener type="BCS.NHibernate.Types.ActivitySaveUpdateListener, BCS.Impl" event="Update"/>
<listener type="BCS.NHibernate.Types.ActivitySaveUpdateListener, BCS.Impl" event="SaveUpdate"/>
<listener type="BCS.NHibernate.Types.ActivityDeleteListener, BCS.Impl" event="Delete"/>
</listeners>
</factory>
</facility>
</facilities>
<include uri="file://modules.cfg.xml" />
</castle>
내가 작업 롤백의 단위가 완벽하게 작동 언급해야하지만 동시에 일부 사용자가 NHibernate에있어.HibernateException : 우리의 작업 단위에 두 개의 열린 세션 모두를 가진 콜렉션을 연관시키려는 잘못된 시도, 다른 한편으로는 이러한 모든 문제를 아버지와 중첩 된 트랜잭션. 우리는 IIS 풀을 ASP.Net 4.0 Classic으로 변경합니다.
우리는 다른 것들을 시도했지만 아무런 효과가 없습니다. 우리의 성 바이너리 버전은 다음과 같습니다
Castle.Facilities.AutoTx 2.5.1.0
Castle.Facilities.NHibernateIntegration 1.1.0.0
Castle.Services.Transaction 2.5.0.0
Castle.Windsor 2.5.1.0
NHibernate.ByteCode.Castle 3.1.0.4000
NHibernate 3.1.0.4000
ASP.Net 4.0
일부는 비슷한 문제가 있거나 과거에 이와 유사한있어?
트랜잭션에서 세션의 객체를 제거하면 문제가 발생합니다. 감사합니다 =) – jpeep