Как реализовать параллелизм в Nhibernat 3.1 - PullRequest
2 голосов
/ 25 сентября 2011

У меня есть проект по nhibernate 3.1. Мне нужно внедрение параллелизма в проекте. Я добавляю "Version" в файл hbm:

 <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)

Ответы [ 2 ]

1 голос
/ 25 сентября 2011

Похоже, вы все делаете правильно.Он должен работать.Попробуйте следующее:

  1. Убедитесь, что ни один другой сеанс не изменяет этот объект (исключение StaleObjectStateException, которое вы получаете, может быть легитимным).

  2. Убедитесь, чточто ничего в самой базе данных не обновляет столбец Version (например, триггер)

  3. Убедитесь, что ничто в вашем коде не изменяет свойство Version.Он предназначен только для использования в NHibernate.

  4. Удалить unsaved-value="0" из идентификатора сопоставления.Посмотрите, сработает ли это после этого.

  5. Обновите свой ответ с помощью трассировки стека и фактических значений версии в базе данных и в объекте (непосредственно перед сохранением объекта).

0 голосов
/ 25 сентября 2011

Полагаю, вам нужно включить динамическое обновление, чтобы заставить работать оптимистичную проверку параллелизма.См. эту запись в блоге .

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