2011-09-25 4 views
2

나는 nhibernate 3.1에 의한 프로젝트를 가지고있다. 프로젝트에서 동시성 구현이 필요합니다. 나는 HBM 파일에 "버전"을 추가 Nhibernat 3.1에서 얼마나 동시성 구현

<class name="Person" table="Person_Person" > 

    <id name="Id" type="Int64" unsaved-value="0" > 
     <generator class="native" /> 
    </id> 

    <version name="Version" /> 

    <property name="FirstName" column="FirstName" 
     type="String(255)" update="true" insert="true" access="property" not-null="false" /> 

    <property name="LastName" column="LastName" 
     type="String(255)" update="true" insert="true" access="property" not-null="false" /> 

    </class> 

이 또한 내가 엔티티 버전 ​​필드를 추가 :
virtual protected int Version { get; set; } 

이 또한 내가 INT 타입으로 데이터베이스에 버전 필드를 추가합니다.

이 구현은 한 번만 정확합니다. 데이터베이스의 버전 값이 '0'일 때만 작동합니다. 테이블에서이 행을 처음으로 업데이트 한 후이 값은 '1'로 변경됩니다. 는 그러나 다음 업데이트 버전 필드가없는 경우 '0'예를 들어 '1'이 메시지에 의해 던져 예외 :

Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [RCISP.Domain.Entities.Person#4] 

어떻게해야합니까?

스택 추적은 다음과 같습니다 당신이 바로 그 일을 같이

at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) 
    at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) 
    at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session) 
    at NHibernate.Action.EntityUpdateAction.Execute() 
    at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) 
    at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) 
    at NHibernate.Engine.ActionQueue.ExecuteActions() 
    at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) 
    at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) 
+0

개인 클래스의 버전은 정확하지만 다른 클래스의 관계는 문제가 있습니다. 예를 들어 패밀리 클래스 (일대 다)에 의한 관계. 엔티티 클래스와 두 hbm 파일 모두에 버전 필드를 추가합니다. 맞습니까? – Ehsan

답변

1

보인다. 그것은 작동해야합니다. 다음보십시오 :

  1. 가 다른 세션이 동일한 개체 (당신이 합법적 수 있습니다 점점 ​​StaleObjectStateException)를 수정하지되어 있는지 확인합니다.
  2. 는 데이터베이스 자체에 아무것도 버전 열 (예 : 트리거)

  3. 코드에서 아무것도 버전 속성을 변경하지 있는지 확인 업데이트 없는지 확인합니다. 그것은 NHibernate 사용만을위한 것입니다.

  4. id 매핑에서 unsaved-value="0"을 제거하십시오. 그 후에 작동하는지 확인하십시오.

  5. 스택 추적과 데이터베이스 및 개체의 실제 버전 값 (개체를 저장하기 직전)을 사용하여 대답을 업데이트하십시오.

+0

이 케이스를 확인했지만 내 문제가 해결되지 않았습니다. 업데이트 행 후에 버전 값이 '1'로 바뀌는가? 행을 업데이트 한 후에 '0'을 유지하지 않아도됩니까? – Ehsan

+0

개체의 버전 값은 nhibernate에 의해 업데이트되고 업데이트하는 동안 데이터베이스의 값과 비교됩니다. 문제를 격리하면 좋은 생각 일 수 있습니다. 문제를 재현하는 독립 실행 형 응용 프로그램을 작성하십시오. – Dmitry

+0

이해할 수 없음 어떻게해야합니까? 더 자세히 설명해주십시오. – Ehsan

0

나는 optimistic 동시성 검사를 작동 시키려면 dynamic-update를 켜야한다고 생각합니다. this blog entry을 참조하십시오.

<class name="Person" table="Person_Person" dynamic-update="true"> 
+0

'버전'은 내 테스트에서 '동적 업데이트'없이 예상대로 작동합니다.** 버전 번호 또는 타임 스탬프없이 버전 관리 **에만 '동적 업데이트'가 필요하지 않습니까? – Dmitry

+0

나는 그것을 검사했다. 내 문제가 해결되지 않았다! – Ehsan

+0

@Dmitry - 아마도 설명서를 잘못 읽었을 것입니다. "동적 업데이트를 사용하면 낙관적 인 잠금 전략을 선택할 수 있습니다."http://knol.google.com/k/nhibernate- 챕터 5 기본 또는 매핑 # 5 % 282E % 291 % 282E % 293 % 282E % 29 % 28C2 % 29 % 28A0 % 29class –