Nhibernate 如何在Nhibernat 3.1中实现并发
我有一个nhibernate 3.1的项目。 我需要在项目中实现并发。 我将“版本”添加到hbm文件:Nhibernate 如何在Nhibernat 3.1中实现并发,nhibernate,concurrency,nhibernate-mapping,maping,Nhibernate,Concurrency,Nhibernate Mapping,Maping,我有一个nhibernate 3.1的项目。 我需要在项目中实现并发。 我将“版本”添加到hbm文件: <class name="Person" table="Person_Person" > <id name="Id" type="Int64" unsaved-value="0" > <generator class="native" /> </id> <version name="Version
<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>
我还按int类型向数据库添加了一个version字段
此实现只正确一次。
它仅在数据库中的版本值为“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”
。看看在那之后是否有效我相信您必须启用动态更新才能使乐观并发检查正常工作。看
“版本”按预期工作,在我的测试中没有“动态更新”。“动态更新”不是只有在没有版本号或时间戳的版本控制中才需要吗?@Dmitry-我不知道,也许我误读了文档“如果启用动态更新,您将可以选择乐观锁定策略:”我检查了这种情况,但我的问题没有得到解决。是否更正了在更新行之后,版本值更改为“1”?更新行后不应保留“0”?对象中的版本值由nhibernate更新,并在更新期间与数据库中的值进行比较。如果你将问题隔离开来,这可能是一个好主意:编写一个独立的应用程序来重现问题。我不知道该怎么办?请进一步解释,你的代码似乎是正确的,它的作品为我。编写一个简单的控制台应用程序,使用一个映射类和版本的NHibernate。您需要隔离问题。单独使用Person类中的版本是正确的,但使用另一个类后的关系是问题。例如,按族类划分的关系(一对多)。我将版本字段添加到两个实体类和两个hbm文件中。这是正确的吗?
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)
<class name="Person" table="Person_Person" dynamic-update="true">