在集群intershop环境中,我们看到很多错误消息。我怀疑应用服务器之间的通信不可靠。
Caused by: com.intershop.beehive.orm.capi.common.ORMException:
Could not UPDATE object: com.intershop.beehive.bts.internal.orderprocess.basket.BasketPO对于本地应用服务器,是否有安全的方法来加载最新的实例。
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方法有帮助吗?
try{
if(null != basket)
basket.refresh();
}
catch(Throwable t){
Logger.error(this, t.getMessage(),t);
}发布于 2017-08-10 13:29:30
你会遇到这个错误,因为乐观锁“失败了”。为了更好地理解这个问题,我将尝试解释乐观锁定是如何工作的,特别是在Intershop ORM层中。
PO表中有一个名为OCA的列(OCA ==乐观控制属性?)。假设两个服务器(或两个不同的线程/事务)试图更新表中的同一行。出于性能原因,默认情况下不涉及DB锁定(例如,通过发出select For update)。相反,当第一线程/服务器在其事务内成功更新行时,它会将OCA加1。
第二线程/服务器从它创建自己的状态时就知道OCA的值。然后,它尝试通过发出类似的查询来更新行:
UPDATE ... OCA = OCA + 1 ... WHERE UUID = <uuid> AND OCA = <old_oca>因为第一个线程/服务器已经增加了OCA,所以这个更新失败(实际上是更新0行),并且当ORM层检测到没有更新任何行时,将抛出上面发布的异常。
您的问题不是服务器间的通信,而是以下两种情况之一:
要解决此问题,您可以:
g216
OFFTOPIC备注:当您知道主键(uuid)时,我不确定为什么要使用getObjectsBySQLWhere。就我记忆而言,如果没有完全迭代,ORMObjectCollection-s应该是闭合的。
更新:如果集群配置不正确,并且无法从节点接收多播,您将无法通过编程解决问题。
发布于 2017-08-09 17:04:14
"ORMObject.refresh()“将缓存的共享状态标记为无效。接下来,对该对象的访问将从数据库中重新加载状态。这会影响性能并增加数据库服务器的负载。
但是:如果"refresh()“方法已经分配给当前事务,则它不会重新加载PO实例状态。
最好是调查并修复服务器通信问题。
发布于 2017-08-10 12:38:03
另一种可能性是,这不是通信问题(我假设是集群中节点之间的组播),而只是有两个请求试图同时更新篮子。示例两个ajax请求更新购物篮中的内容。
我会避免尝试“修复”orm,这只会带来更多的伤害而不是好处。而是做进一步的调查并发回更多的信息。
https://stackoverflow.com/questions/45580096
复制相似问题