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