编辑:
结果是在这种情况下,因为我使用的是“版本”注释,所以我使用的是乐观锁定,而不是悲观锁定。
如果我删除版本,因此禁用乐观锁定。悲观的锁定接管了工作,性能显着下降。
所以我想我必须忍受乐观的锁定和偶尔的例外。有更好的解决方案吗?

原版的:
我目前通过ajp在apache 2.2负载均衡器中有多个tomcat实例。后端系统处于休眠状态。该系统为多个用户和请求提供服务,对于请求,系统将从用户帐户中扣除一个信用额度。

我使用hibernate的悲观锁定来管理信用扣除。
我不时在日志中的用户帐户对象上获得以下内容:

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

Code

private boolean decUserAccountQuota(UserAccount userAccount, int creditDec) {

        if(userAccount.getBalance() <1) return false;
        String userName = userAccount.getUsername();
        Manager manager = getManager(userName);


        try{
            manager.beginTransaction();
            manager.refresh(userAccount, LockMode.UPGRADE); //this uses pessimistic locking, this calls sessionFactory.getCurrentSession().refresh();
            userAccount.setBalance(userAccount.getBalance()-creditDec);
            manager.commitTransaction(); //this causes the Exception
        }catch(Exception exp){
            exp.printStackTrace();
            manager.rollbackTransaction();
            return false;
        }finally{
            manager.closeSession();
        }
        return true;
    }



问题:



如何防止此异常发生。这里发生什么
有多个线程尝试更新同一实体,一个线程
成功,因此,当下一个线程提交数据时,它
看到它已经被修改并最终抛出
StaleObjectStateException。但是如果我已经在使用悲观主义
锁定,异常怎么仍会发生?
在性能和完整性方面是否有更好的方法
管理用户帐户信用系统?

最佳答案

您的Hibernate实体在XML Hibernate映射中使用@Version批注或定义<version>。这将启用Hibernate提供的乐观锁定。

如果按照您的描述明确使用悲观锁定,则删除上述内容应该可以解决您的问题。

更多信息here

关于java - 在Hibernate中如何使用悲观锁来处理“StaleObjectStateException”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25396708/

10-10 14:23