У меня есть объект, сопоставленный в NHibernate с оптимистичным контролем параллелизма, использующим столбец временной метки SQL в качестве номера версии. Отображение выглядит следующим образом:
<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 — это подкласс базового класса Entity, для которого оптимистическая блокировка установлена на версию.