【问题标题】:How do I ensure a value being updated with Hibernate hadn't been changed in the meantime since I read it?我如何确保使用 Hibernate 更新的值在我阅读它的同时没有被更改?
【发布时间】:2010-09-25 06:16:34
【问题描述】:

我有一个问题,我想使用 Hibernate 从数据库中读取一个对象,更改一个值,然后保存该对象。如果更改值需要一些时间,那么确保数据库中的基础对象没有更改的最佳方法是什么?我在一个事务(和一个会话)中执行此操作。

代码看起来像:

// Load from DB

Criteria crit = session.createCriteria( Dummy.class ).add( Restrictions.eq("id", 5) );

Dummy val = crit.uniqueResult();

// Processing time elapses.

// Update value of dummy.

val.x++;

// Save back to database. But what if someone modified the row with ID  = 5 in the meantime, and changed the value of x?

session.saveOrUpdate( val );

【问题讨论】:

    标签: java sql multithreading hibernate transactions


    【解决方案1】:

    您可以使用悲观锁虽然我不会这样做,但它可能对您的情况有用。

    由于您的对象是从数据库中检索到的,因此您必须锁定数据库,以便在您使用它时没有其他人修改您的对象。

    为此,您应该lock您的对象。

    session.lock( myObject , LockMode.UPGRADE );
    

    试一试。

    编辑

    这可能是你的更多:

    // Load from DB
    
    Criteria crit = session.createCriteria( Dummy.class ).add( Restrictions.eq("id", 5) );
    
    crit.setLockMode( LockMode.UPGRADE  ); // issues a SELECT ... for UPDATE... 
    
    Dummy val = crit.uniqueResult();
    
     etc.etc
    

    Criteria.setLockMode()

    【讨论】:

    • LockMode.UPGRADE 的问题发生在没有返回值时(即没有ID 为5 的行)。所以我的程序可能想插入自己的新行,但是如果同时另一个线程插入到表中怎么办?
    • 迈克尔。这就是您所说的:“我如何锁定数据库中甚至不存在的记录并阻止其他人插入它?”阅读它,直到你发现这种说法的问题。
    【解决方案2】:

    我建议改为乐观锁定。您将“版本”属性添加到您的对象,然后休眠在最后执行更新操作并验证版本在您读取对象后没有更改。通常比悲观锁定更好的设计(没有什么比发现那些数据库死锁!)。

    当然,问题仍然存在,如果对象发生了变化,你打算怎么做?

    【讨论】:

      猜你喜欢
      • 2017-12-10
      • 2021-11-29
      • 2021-04-18
      • 2014-10-23
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多