我有一个 Web 应用程序,其中包含具有两个操作的 Web 服务: createA
和createB
。为端点注册了一个处理程序。该处理程序在收到请求时打开一个 session 并启动一个事务。然后执行请求的操作的代码。在发送回响应之前,事务已提交并关闭 session 。
代码createA
包括创建 A
类型的实体并使用 Session.save()
持久化它方法。在 Debug模式下,Session.save()
之后调用后,可以看到session的ActionQueue中有一个插入。
代码createB
组成:
- 检索先前创建的
A
类型的实体 - 创建实体
B
引用A
的实例(B 具有代表关联A
的属性) - 正在更新
A
引用B
的新实例 - 调用
Session.save()
对于B
的新实例 - 调用
Session.update()
对于A
的新修改实例
但是,在DEBUG模式下,调用Session.save()
后和Session.update()
,对应Session的ActionQueue为空。但是,事务提交后,我可以在数据库中看到创建的实体。
操作createA
和createB
按此顺序调用,无需 DEBUG。执行createB
时出现错误当它尝试检索 A
的实例时先前使用标准和 Session.list()
创建方法。问题是 A
的实例未找到。
但是,如果我在 DEBUG 中重复相同的操作顺序或使用 Thread.sleep(15s)
在两个操作的调用之间, A
的实例可以找到。
谢谢
<小时/>编辑:我忘了准确地说它可以在某些机器上运行,但不能在其他机器上运行。我没有看到这些机器之间有任何差异。
最佳答案
如果您对 createA 和 createB 使用相同的 Hibernate session ,那么它就会工作。您可以将Hibernate session 存储在Http session 中来实现此目的(注意同步对 session 对象的访问,因为来自同一浏览器 session 的请求可以在不同的线程中进行)。
您的问题是,Hibernate 为每个 session 打开一个新的数据库连接。现在你的数据库好像没有同步语句。在数据库中,可能会发生选择在插入完成之前到达的情况。那么这种情况是否发生就取决于所涉及计算机的速度。使用 Debug模式或 sleep() 可以使一台计算机变慢,这样就不会再遇到问题了。
如果您想继续进行这两个过程的两个不同 session ,您可以
- 查找数据库的事务模式。某些数据库存在脏读,未完成正确的锁定或同步。检查一下您是否不小心使用了这种模式。
- 如果您的数据库有更改计时和同步的参数,请检查 JDBC 参数(它们可以在 hibernate connection.url 中使用)。
- 检查您的连接池(如果您正在使用连接池)。
关于java - Hibernate 误读,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10933276/