【问题标题】:hibernate multi-thread-multi-session and objects休眠多线程多会话和对象
【发布时间】:2012-06-29 13:50:20
【问题描述】:

关于设置的一些事实:

  • 这是一个基于 Tomcat 的应用程序(尽管问题也出现在 Tomcat 的上下文之外 - JUNIT)
  • 不使用 Spring
  • 每个线程都有自己的 Hibernate Session(在 TLS 上)
  • 对象以混合方式保存/加载,即ObjA可能由线程A创建,然后由线程B操作,甚至后来由线程 A 更新,然后再次由线程 Z 操作,但这次使用 HQL

进行上述设置后,我遇到了以下错误:

  • org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions
  • org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

我的理解是这样的

  • 这都与 Hibernate 的 Session 有关,因为会话“拥有”“附加”到它的对象(它创建/加载的对象)
  • 可能还有缓存问题

问题很明显:

  • 我是否了解核心问题(上)?
  • 如何避免此类问题?
  • 是否有经验法则可以帮助避免这些问题?
  • 是否可以使用 Spring 来解决这个问题(请具体说明一下)?
  • 是否会在从数据存储中获取每个对象后从 Session 中分离它,然后在更新之前将其附加到 Session 是处理它的理想方式吗?

如果我只使用一个 Session 对象,我当然可以避免所有这些,但这听起来……阻塞(线程方面)。

我确信这些问题很久以前就解决了,只需要找到它(无需重新发明轮子)。

【问题讨论】:

  • 第二个异常 (StaleObjectStateException) 如果您有多个线程同时读取和写入同一个数据库实体,则完全有效,例如线程 1 读取对象 A,线程 2 读取对象 A,线程 1 写入对象 A,线程 2(尝试)写入对象 A - 瞧,异常。你的代码应该处理这个。
  • @JonoB 对,我的代码应该处理它,这就是我的问题:) 我该如何处理它?我想我可以想出我自己的方式,但我相信有一些优雅的方式可以让这里的人分享。 如何非常重要。
  • 我的第一个建议是阅读乐观锁定。
  • 是的,从StaleObjectStateException 中恢复是一回事,但另一个 (....proxy with two open Sessions) 呢?这个是杀手,除非我找到一些经验法则,比如......甚至不知道!
  • 在问题中看到一些代码会很好;)

标签: java multithreading hibernate session


【解决方案1】:

对象已附加到 Hibernate 会话,是的。它一次只能附加一个,是的。除非您关闭 Hibernate 会话,否则您可以尝试 evict() 对象,从而将其与会话分离,从而可以将其加载到另一个线程中。问题是,这可能不切实际,具体取决于您的程序流程。

【讨论】:

  • 为什么这可能不切实际?请详细说明。我想我知道……看,我拿东西。没有延迟加载。然后,经过一些处理,我打电话给saveOrUpdate()。现在我想你可以谈谈你对这个具体案例的看法了:)
  • 这取决于您的应用程序如何工作,我的意思是,线程如何工作。它们是简单的终止线程,只是碰巧以不可预测的混乱顺序在实体上工作,还是它们是无休止的循环威胁,轮询数据库并以这种方式获取它们?在后一种情况下,驱逐、保存和刷新可能有点太不可预测了。我总是觉得使用驱逐不干净。我宁愿真正关闭会话并尝试以有序的方式处理行。调用 saveOrUpdate() 然后 evict() 应该可以工作。
  • 我相信线程以不可预知的方式访问实体,它们确实在对数据存储进行无限循环轮询。当它找到一个相关实体时,它会加载它、操作它并继续。与此同时,另一个线程可能会访问同一个实体。
  • 嗯,那么 Hibernate Optimistic Locking 呢? Link 它可以使您免于手动驱逐实体,并管理对行的所有访问尝试都是有序的。
【解决方案2】:

在获取对象之前调用clear()

【讨论】:

    猜你喜欢
    • 2015-06-12
    • 2015-04-11
    • 2011-06-08
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    相关资源
    最近更新 更多