gpt4 book ai didi

nhibernate - NHibernate StaleObjectStateException 之后如何优雅地合并对象图?

转载 作者:行者123 更新时间:2023-12-04 04:35:48 39 4
gpt4 key购买 nike

我们试图在抛出 StaleObjectStateException 后合并对象以保存合并的副本。

这是我们的环境状况:

  • 列表项
  • 多用户系统
  • WPF 桌面应用程序、SQL Server 2008 数据库
  • NHibernate 3.1.0.4000, FluentNHibernate 1.2.0.712
  • 全局、长期运行的 NHibernate session [暂时。我们知道每个演示者 session 是推荐的模式,但目前在我们的项目计划中没有时间进行转换。]
  • 自上而下的保存和属性导航(也就是说我们在域图中保存了顶级对象(这里称为Parent))
  • .Cascade.AllDeleteOrphan() 在大多数情况下使用。
  • 用户独占域图中的某些对象,但共享父对象的所有权。
  • Children 对象的导航属性不存在。
  • 所有类都有数字 ID 和数字版本字段。

  • 用例:
  • 用户 1 启动应用程序并打开父级。
  • 用户 2 启动应用程序并打开 Parent。
  • 用户 2 添加了一个 child (此处为 C2)。
  • 用户 2 保存父级。
  • 用户 1 添加了一个 child (此处为 C1)。
  • 用户 1 保存父级。
  • 用户 1 收到一个 StaleObjectStateException(这是正确的)

  • 我们希望优雅地处理异常。
    因为用户共享父级的所有权,所以用户 1 应该能够成功保存,并且将父级与他的新 child 和用户 2 的 child 一起保存。

    当 SOSE 被抛出时,根据 Ayende ( http://msdn.microsoft.com/en-us/magazine/ee819139.aspx):

    your session and its loaded entities are toast, because with NHibernate, an exception thrown from a session moves that session into an undefined state. You can no longer use that session or any loaded entities



    C1 已经被现在不可用的 session 分配了一个 ID 和版本号。 (我希望没有。)

    我们如何结合使用 ISession.Merge() 和 ISession.Refresh() 来获得一个新保存的同时具有 C1 和 C2 的 Parent ?

    我们尝试了许多神秘的排列方式,但都没有完全奏效。
    通常,“行已被另一个事务更新或删除(或未保存的值映射不正确”或 ODBC 级别的实际 ID 冲突。

    目前我们的理论:
  • 重置 C1 上的版本号(以防止“未保存的值映射不正确”)
  • 获取新 session
  • 新 session 。刷新(C1);
  • newParent = newSession.QueryOver[...]
  • newParent.Add(C1);
  • newSession.SaveOrUpdate(newParent)

  • 但是,所有文档都表明 newSession.Merge 应该就足够了。

    其他用作研究的帖子:
    Fluent NHibernate Newbie: Row was updated or deleted by another transaction
    Is there an alternative to ISession.Merge() that doesn't throw when using optimistic locking?
    StaleObjectstateException row was updated or deleted by
    How I can tell NHibernate to save only changed properties
    Hibernate (JPA): how to handle StaleObjectStateException when several object has been modified and commited (java,但相关,我认为)

    最佳答案

    Because the users share ownership of the parent, User 1 should be able to save successfully, and save the Parent with both his new child, and User 2's child.



    为什么不禁用子集合的乐观锁定?然后任何人都可以添加 child ,它不会增加 parent 的版本。

    否则,这是我当前项目用于 session 可能引发的所有可恢复异常的解决方案(例如,与 DB 的连接丢失、外键被违反……):
  • 调用前session.Flush() session 被序列化为 MemoryStream .
  • 如果 session.Flush()transaction.Commit()抛出一个可恢复的异常,原始 session 被释放,保存的 session 被反序列化。
  • 调用屏幕然后获取 session 在异常后恢复的信息,并再次调用第一次打开屏幕时调用的相同查询。并且因为所有修改过的实体仍在恢复的 session 中,所以用户现在处于按下保存之前的状态。
  • 关于nhibernate - NHibernate StaleObjectStateException 之后如何优雅地合并对象图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8056959/

    39 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com