У меня есть сущность, сопоставленная в 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, для которого оптимистическая блокировка установлена в версию.