【问题标题】:Hibernate : Does it reload the object after get() with LockOptions.UPGRADEHibernate:它是否在 get() 之后使用 LockOptions.UPGRADE 重新加载对象
【发布时间】:2016-05-16 09:59:14
【问题描述】:

我遇到了一个问题,我使用get(Serializable,Class,LockOptions) 方法和LockOptions.UPGRADE 获取行上的锁。

正在获取锁的对象已经存在于会话中。 执行 select ... for update 后,我发现如果表中的相应行在初始获取对象之后和get(Serializable,Class,LockOptions) 之前已更改,则该方法不会返回更新的对象。

我想澄清以下内容, 这是因为我试图在其对象已加载到会话缓存中的行上获取锁。

Hibernate 是否只是在后台触发 select ... for update,但不重新加载对象,而是从会话缓存中获取一个对象(如果找到)?

以下是关于我如何获取锁的代码 sn-p。

List<MyObject> listOfMyObject = dao.getListOfMyObjects();

for(MyObject m : listOfMyObject ){
   m = session.get(id,MyObject.class,LockOptions.UPGRADE);
   //
}

锁定机制工作正常。当锁被 ThreadOne 事务持有时,我可以看到另一个 ThreadTwo 事务正在等待获取锁。现在当 ThreadOne 事务释放锁时,第二个事务通过session.get(id,MyObject.class,LockOptions.UPGRADE) 方法获取它,返回的对象没有 ThreadOne 完成的更新值。

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    理想情况下,当您使用 LockOptions.Upgrade 时,它​​是一种悲观锁定。

    理想情况下,它不应该允许任何其他事务来更改记录,因为它是对该数据库行的一种悲观锁定。

    理想情况下,不要使用悲观锁定,而是通过使用某种版本/时间戳列来进行乐观锁定,您可以在其中以编程方式进行更多控制。

    【讨论】:

      【解决方案2】:

      是的,根据Hibernate docssession.get(Serializable,Class,LockOptions) 从会话中加载该实例(如果它已经存在)。对于您的情况,您可能希望在 session.get(Serializable,Class,LockOptions) 之后立即使用 session.refresh(Object object) 从数据库中重新读取实例的状态。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-10
        • 2012-03-04
        • 2020-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多