我正在处理nhibernate中的并发问题,我不确定我做得对。我使用版本字段,当事务被调用时,我认为如果版本字段被另一个进程更改,将抛出StaleObjectStateException。我抓住了这个例外并处理了这个案例,似乎有效。
但我想知道的是,每次抛出异常时,NHibernate都会在我的log4net-Logfile中产生一个ERROR。我已经将NHibernate的loglevel设置为ERROR,因为我认为如果发生错误我应该感兴趣。但我对所有关于并发冲突的消息不感兴趣,因为我不认为这是一个错误。
所以可能是我做错了什么?它是通过捕获异常来处理并发的正确方法吗?
更新:这是nhibernate在我的日志文件中放置的内容:
2012-06-21 16:47:30,546 ERROR NHibernate.Event.Default.AbstractFlushingEventListener: Could not synchronize database state with session NHibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Delta.FollowUp.Model.CFollowUp#60003] bei 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) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:Zeile 2780. bei 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) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:Zeile 2692. bei NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:Zeile 3000. bei NHibernate.Action.EntityUpdateAction.Execute() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Action\EntityUpdateAction.cs:Zeile 79. bei NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:Zeile 136. bei NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:Zeile 126. bei NHibernate.Engine.ActionQueue.ExecuteActions() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:Zeile 170. bei NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:Zeile 241.
答案 0 :(得分:1)
当出现并发问题时,您所做的工作取决于应用程序。在很多情况下,捕获异常并重试工作单元就足够了 - 但是定义工作单元可能会变得棘手。根据您的具体情况,再次加载实体并再次进行更改然后保存它可能就足够了,但这实际上取决于您的应用程序。
基本上,该异常意味着另一个线程/进程已经更改了数据库中的实体,因此您现在需要做出相应的反应。 NHibernate将其记录为错误,因为使用版本字段意味着乐观并发,您假设没有其他任何东西会改变您正在更改的行,所以如果某些内容确实改变了其中一行,那么您需要处理它。
答案 1 :(得分:1)
如果您不想要记录NHibernate错误,只需删除NHibernate的记录器,将其设置为FATAL级别,或以某种方式过滤异常。
你仍然可以捕获异常,处理它,重新抛出它,记录它,等等。