【问题标题】:Hibernate: Increment a integer fieldHibernate:增加一个整数字段
【发布时间】:2011-07-22 20:04:59
【问题描述】:

我想使用 Hibernate 将数据库表中的字段增加 1。

我可以通过简单地加载一个对象、增加值并更新对象来做到这一点,但是如果另一个线程出现并更新加载和更新之间的字段,那么值将被破坏。

所以我直接在数据库上调用了更新:

Query updateHits = createQuery(
    "UPDATE Job SET hitCount = hitCount + 1 WHERE id = :jobId" );
updateHits.setInteger( "jobId", job.getId() );
updateHits.executeUpdate();

但是我的理解是,这绕过了数据库中的乐观锁定,我目前遇到了 SQL 服务器中的死锁问题,我认为这是罪魁祸首。

有没有一种方法可以在不直接调用更新并保持数据完整性的情况下增加字段?

【问题讨论】:

  • 可能想检查一下您的锁是如何创建的。如果您获得该更新的表锁定,则出现问题。如果你得到一个行锁,我看不出它会如何导致死锁。
  • 我实际上已经设法解决了死锁问题,只需确保此更新是在事务中运行的最后一条语句。但是我仍然有兴趣了解更好的解决方案。
  • 你的“increment-by-query”解决方案比处理悲观锁要好十倍,尤其是在你处理多线程和长时间运行的事务时

标签: sql-server hibernate hql


【解决方案1】:

我可以通过简单地加载一个 对象,增加值和 更新对象但是如果另一个 线程出现并更新 在负载和之间的字段 更新然后值将变为 损坏。

如果第二个线程也使用休眠并且您使用休眠版本控制 (@Version),则首先提交并更改对象的线程将在对象上设置新版本。

当第二个线程提交进来时,hibernate 会检查乐观锁是否失败,如果我没记错的话,会抛出一个异常——StaleObjectException。如果您的并发代码周围有一个 catch 块,您将有机会再次加载该对象并尝试您的更新,如果它有意义的话。如果您使用的是 JPA,则会抛出 OptimisticLockException。

Hibernate Optimistic Concurrency Control Section 上有大量信息。

干杯!

【讨论】:

    猜你喜欢
    • 2012-05-05
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 2012-01-31
    相关资源
    最近更新 更多