【问题标题】:Hibernate pessimistic lock between two web apps两个 Web 应用程序之间的休眠悲观锁
【发布时间】:2015-12-21 05:49:23
【问题描述】:

我有两个不同的 Web 应用程序来更新数据库表实体。两个不同的应用程序使用相同的实体结构(但应用程序对这些实体有自己的单独代码)

public class Users implements java.io.Serializable {
    // Fields
    private String username;
    private String password;
    private Double credit;

    //..setters getters

}

这两个应用都有自己的服务来更新用户的信用。

App1 用 ff 锁定用户实体:

User user = (User) userDao.get(User.class, userName,LockMode.PESSIMISTIC_WRITE);

//update here

App2 用 ff 锁定实体:

User user = (User) userDao.get(User.class, userName,LockMode.UPGRADE);

//update here

现在,出现了两个应用程序同时更新用户信用的竞争条件。两个应用程序在调用userDao.get(...) 期间检索到了 1.0 的信用。 App1会加10,而App2会加20。两个事务提交后,用户信用是21。但是这些更新后的预期用户信用应该是31。是不是因为这两个应用程序之间的LockMode不同(即LockMode .UPGRADE && LockMode.PESSIMISTIC_WRITE)?。还是因为它们在不同的 Web 服务器上运行(注意:它们使用相同的数据库)。根据我对 lockmode pessimistic 的理解,它应该是 31,因为另一个事务将等待第一个获得锁的事务。有人可以解释此更新异常的可能原因吗?

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    在我看来,您应该使用LockMode.PESSIMISTIC_READ 而不是LockMode.PESSIMISTIC_WRITE。根据文档:

    悲观阅读。实体管理器会立即锁定实体 事务读取它。锁一直持有到交易 完成。当您要使用以下方式查询数据时使用此锁定模式 可重复读语义。换句话说,您要确保 连续读取之间不会更新数据。这种锁定模式不 阻止其他事务读取数据。

    悲观写。实体管理器会立即锁定实体 事务更新它。这种锁定模式强制序列化 尝试更新实体数据的事务。这种锁定模式是 通常在更新失败的可能性很高时使用 并发更新事务。

    使用PESSIMISTIC_WRITE,您可以进行脏读。

    【讨论】:

      猜你喜欢
      • 2014-11-12
      • 2017-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多