当我在同一个对象/表上使用 HQL 进行读取时,hibernate 为什么执行更新 sql 语句?
发生的情况是我正在读取一些记录,比如颜色 = 红色的汽车,它返回 10 辆汽车。然后我迭代这 10 辆汽车,并更新该汽车对象中的日期,即 car.setDate(5/1/2010)。然后我再次读取《汽车》中的颜色 = 绿色的内容。我打开了 sql 日志记录,我注意到当我调用 query.list() 时,它实际上会打印出一些更新语句到 Cars 表,并且我最终得到了锁等待超时。另请注意,这一切都是在单个数据库事务中完成的,因此我可以理解锁等待超时 - 似乎我在正在读取的表上有一个锁,并且在同一个事务中我试图更新它在我释放桌子上的锁之前。但似乎它不应该尝试运行 sql 来更新这些记录,直到我调用提交时事务结束?这都是使用 hibernate 的 HQL 来执行读取。我根本没有直接调用任何东西来进行保存,我只是在执行 car.setDate。
What's happening is i'm performing a read of some records, say Car where color = red, and it returns 10 cars. Then I iterate over those 10 cars, and update a date in that car object, i.e. car.setDate(5/1/2010). Then I perform another read from Cars where color = green. I have sql logging turned on and I noticed when i call query.list() it actually prints out some update statements to the Cars table, and I end up getting a lock wait timeout. Also note, this is all done in a single database transaction, so I can understand the lock wait timeout - it seems like i have a lock on the table i'm reading from, and in that same transaction i'm trying to update it before i release the lock on the table. But it seems like it shouldn't be trying to run the sql to update those records until the end of the transaction when i call commit? This is all using hibernate's HQL to perform the reads. I'm not calling anything directly at all to do the saves, i'm just doing car.setDate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
数据库写入由会话上的 FlushMode 控制。默认情况下,hibernate 使用
FlushMode.AUTO
,这允许它在认为合适的时候执行session.flush()
。session.flush()
会导致会话中未提交的数据写入数据库。在提交会话(或回滚)之前,将会话数据刷新到数据库不会使其永久化。根据您的数据库表/行锁定策略,作为此事务的一部分更新的行可能会被锁定以进行读或读/写访问。我认为答案在数据库中 - 您的表是否有支持您的用例的适当锁定策略?
The database writes are controlled by the FlushMode on your session. By default, hibernate uses
FlushMode.AUTO
, which allows it to perform asession.flush()
whenever it sees fit. Asession.flush()
causes uncommitted data on the session to be written to the database. Flushing session data to the database does not make it permanent until you commit your session (or roll it back). Depending on your database Table/Row locking strategy, the rows that have been updated as part of this transaction may be locked for Read or Read/Write access.I think the answer is in the database- do your tables have the appropriate locking strategy that supports your use case?