首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >intershop ORMException无法更新-刷新ORMObject

intershop ORMException无法更新-刷新ORMObject
EN

Stack Overflow用户
提问于 2017-08-09 09:01:49
回答 3查看 581关注 0票数 1

在集群intershop环境中,我们看到很多错误消息。我怀疑应用服务器之间的通信不可靠。

代码语言:javascript
复制
Caused by: com.intershop.beehive.orm.capi.common.ORMException: 
Could not UPDATE object: com.intershop.beehive.bts.internal.orderprocess.basket.BasketPO

对于本地应用服务器,是否有安全的方法来加载最新的实例。

代码语言:javascript
复制
   BasketPO basket = null;
        try{
            BasketPOFactory factory = (BasketPOFactory) NamingMgr.getInstance().lookupFactory(BasketPOFactory.FACTORY_NAME);
            try(ORMObjectCollection<BasketPO>baskets = factory.getObjectsBySQLWhere("uuid=?", new Object[]{basketID},CacheMode.NO_CACHING);){
                if(null != baskets && !baskets.isEmpty()){
                    basket = baskets.stream().findFirst().get();
                }
            }
        }
        catch(Throwable t){
            Logger.error(this, t.getMessage(),t);
        }

ORMObject#refresh方法有帮助吗?

代码语言:javascript
复制
    try{
        if(null != basket)
              basket.refresh();
    }
    catch(Throwable t){
        Logger.error(this, t.getMessage(),t);
    }
EN

回答 3

Stack Overflow用户

发布于 2017-08-10 13:29:30

你会遇到这个错误,因为乐观锁“失败了”。为了更好地理解这个问题,我将尝试解释乐观锁定是如何工作的,特别是在Intershop ORM层中。

PO表中有一个名为OCA的列(OCA ==乐观控制属性?)。假设两个服务器(或两个不同的线程/事务)试图更新表中的同一行。出于性能原因,默认情况下不涉及DB锁定(例如,通过发出select For update)。相反,当第一线程/服务器在其事务内成功更新行时,它会将OCA加1。

第二线程/服务器从它创建自己的状态时就知道OCA的值。然后,它尝试通过发出类似的查询来更新行:

代码语言:javascript
复制
UPDATE ... OCA = OCA + 1 ... WHERE UUID = <uuid> AND OCA = <old_oca>

因为第一个线程/服务器已经增加了OCA,所以这个更新失败(实际上是更新0行),并且当ORM层检测到没有更新任何行时,将抛出上面发布的异常。

您的问题不是服务器间的通信,而是以下两种情况之一:

  • 多个服务器/线程尝试更新同一对象;
  • 数据库中有绕过ORM层的直接更新(可能性较小);

要解决此问题,您可以:

  1. 完全避免了这种情况(我强烈推荐:-);
  2. 使用ISH锁定框架(非常繁琐imHo);
  3. 使用由ISH ORM层和Oracle支持的准锁定(注意潜在的性能问题、死锁、错误);
  4. 使用Java锁定-但由于服务器运行在不同的JVM-s中,这很少出现;

g216

OFFTOPIC备注:当您知道主键(uuid)时,我不确定为什么要使用getObjectsBySQLWhere。就我记忆而言,如果没有完全迭代,ORMObjectCollection-s应该是闭合的。

更新:如果集群配置不正确,并且无法从节点接收多播,您将无法通过编程解决问题。

票数 2
EN

Stack Overflow用户

发布于 2017-08-09 17:04:14

"ORMObject.refresh()“将缓存的共享状态标记为无效。接下来,对该对象的访问将从数据库中重新加载状态。这会影响性能并增加数据库服务器的负载。

但是:如果"refresh()“方法已经分配给当前事务,则它不会重新加载PO实例状态。

最好是调查并修复服务器通信问题。

票数 0
EN

Stack Overflow用户

发布于 2017-08-10 12:38:03

另一种可能性是,这不是通信问题(我假设是集群中节点之间的组播),而只是有两个请求试图同时更新篮子。示例两个ajax请求更新购物篮中的内容。

我会避免尝试“修复”orm,这只会带来更多的伤害而不是好处。而是做进一步的调查并发回更多的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45580096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档