2016-05-16 137 views
0

我正面临一个问题,即通过使用get(Serializable,Class,LockOptions)方法和LockOptions.UPGRADE获取该行的锁。休眠:它是否在get()和LockOptions.UPGRADE后重新加载对象

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

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

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

以下是我如何获取锁定的代码片段。

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完成的更新值。

回答

0

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

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

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

0

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