1

SQL 타임 스탬프 열을 버전 번호로 사용하여 낙관적 동시성 제어로 NHibernate에 매핑 된 엔티티가 있습니다. 매핑은 다음과 같다 : 내가 무슨 테스트입니다<Version>이 사용되고 데이터가 데이터베이스에서 변경되었을 때 NHibernate가 StaleObjectStateException을 던지지 않는다

<class name="Entity" optimistic-lock="version" discriminator-value="0"> 
    <id name="id"> 
     <generator class="native" /> 
    </id> 
    <version name="Version" column="Version" generated="always" unsaved-value="null" type="System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 
    ... 
    <subclass name="ChildEntity" discriminator-value="1" /> 
</class> 

때 얻을 레코드의 업데이트 사이의 데이터베이스 변경의 행의 데이터. 이렇게하려면 NHibernate에 의해 업데이트되는 과정에있는 테이블의 레코드 중 하나에 대해 직접 업데이트 문을 실행하고 있습니다. 이 직접 업데이트는 테이블의 레코드 버전 번호를 변경합니다.

예상대로 NHibernate 관리 업데이트가 특정 행에 표시되지 않습니다 (좋음). 그러나 커밋 중에 예외가 발생하지 않습니다. 내가 트랜잭션을 롤백하고 사용자에게 알릴 수 있도록 트랜잭션이 커밋되었을 때 StaleObjectStateException이 발생할 것으로 예상했다. 이것이 예상 된 행동이 아닌가? 내가 놓친 게 있니?

_session.BeginTransaction(); 
... 
// load objects in session 
IList<ChildEntity> toChange = _session.Find('some condition'); 
foreach (var itemToChange in toChange) 
{ 
    itemToChange.Status = Status.Updated; 
} 
... 
_session.Transaction.Commit(); 

항목은 동일한 세션에 속하는 모든 작업이 하나의 트랜잭션 내에서 완료 : 트랜잭션을 커밋

내 코드는 다음과 같이 보입니다. ChildEntity는 optimistic-lock이 version으로 설정된 Entity 기본 클래스의 하위 클래스입니다.

답변

0

내 테스트가 부정확 한 것으로 보입니다. 테스트에서 다른 트랜잭션이 레코드를 업데이트 한 후에 가져 오려고했습니다. 이 다른 업데이트로 인해 행이 업데이트를받을 수 없으므로 업데이트를 시도하지 않았습니다. Get을 실행 한 후 테스트를 변경하여 StaleObjectStateException이 예상대로 발생했습니다.

죄송합니다.

5

어떻게 데이터를 수정하나요? StaleObjectException는, Hibernate가 행의 갱신을 시도해, 버젼 번호가 동일하지 않은 경우에만 Throw됩니다. 다른 열은 부적절합니다. 테스트 할 때 버전 번호를 업데이트하지 않을 수 있습니까?

전제는 이것이다 :

A. 사용자 버전과 데이터베이스에서 & B get 및 객체 = 1

SQL : SELECT [object] FROM [TABLE] where id = [id] and Version = 1

2 버전을 변경

B. 사용자 : 업데이트 개체

SQL : UPDATE [TABLE] SET [object] (& Set Version = 2) where id = [id] and Version = 1 반환 한 행

C. 사용자 B 시도를 업데이트 개체를 업데이트하지만 StaleObjectException을 version = 1 (1 단계에서 얻은 버전)의 업데이트 개체로 가져 오면 데이터베이스의 레코드가 0으로 업데이트됩니다.

SQL : UPDATE [TABLE] SET [object] where id = [id] and Version = 1은 0 행을 업데이트하고 StaleObjectException을 반환합니다.