我有一个Web应用程序,它包含一个包含两个操作的Web服务:createA
和createB
。为端点注册了一个处理程序。此处理程序打开会话并在收到请求时启动事务。然后执行所请求操作的代码。在发回响应之前,事务已提交,会话已关闭。
createA
的代码包括创建A
类型的实体并使用Session.save()
方法对其进行持久化。在DEBUG模式下,在调用Session.save()
之后,我可以看到会话的ActionQueue中有一个插入。
createB
的代码包含:
A
B
实例的实体A
(B具有代表关联A
的属性)A
以引用B
Session.save()
B
Session.update()
A
但是,在DEBUG模式下,在调用Session.save()
和Session.update()
之后,相应Session的ActionQueue为空。但是,在事务提交之后,我可以在数据库中看到创建的实体。
在没有DEBUG的情况下,按此顺序调用操作createA
和createB
。创建B
时,在尝试检索先前使用条件和A
方法创建的Session.list()
实例时,会出现错误。问题是找不到A
的实例。
但是,如果我在DEBUG中重复相同的操作序列或在两个操作的调用之间使用Thread.sleep(15s)
,则可以找到A
的实例。
由于
编辑:我忘了确切地知道它适用于某些机器而不适用于其他机器。我认为这些机器之间没有任何差异。
答案 0 :(得分:1)
如果对createA和createB使用相同的Hibernate会话,那么它将起作用。您可以在Http会话中存储Hibernate会话以实现此目的(注意同步对会话对象的访问,因为来自同一浏览器会话的请求可以在不同的线程中进行)。
您的问题是,Hibernate为每个会话打开一个新的数据库连接。现在你的数据库似乎没有同步语句。在插入完成之前,选择到达的数据库中可能会发生这种情况。然后,如果发生这种情况,它只取决于所涉及的计算机的速度。使用调试模式或sleep()可以使一台计算机变慢,这样就不再有问题了。
如果您想为这两个程序继续两个不同的会话,您可以
答案 1 :(得分:1)
问题是当您调用Session.save()时,Hibernate不会将实体保存到数据库。它只是准备语句以便稍后执行。当事务结束或刷新会话时会发生这种情况。
您的B号呼叫有时可能会在A请求的交易结束之前发生。这就是为什么如果你等了一会儿就行了。
尝试在保存调用后添加session.flush()。这将强制Hibernate将更改保留到DB。