tb_0030出现违反唯一性约束的问题_违反表的唯一约束性try catch-程序员宅基地

技术标签: 问题处理  

tb_0030是SEMQ的待确认消息表,存储已接收但等待发送方确认已送达的记录,f003v_0030是确认记录键,可以唯一对应到系统范围内的所有SEMQ实例中的待发送记录.

f003v_0030由节点类型,节点id,SEMQ实例id,SEMQ存储id,记录编号组成.

tb_0030在f003v_0030上建立唯一索引.可以提高定位速度.

 

运行过程中出现了重复insert导致违反约束的情况.---虽然不会造成逻辑错误,但浪费了资源.

检查代码发现,在处理接收到的消息时,检查是否已经接收过此消息,即使判定已经接收过,仍先执行insert,出错后检查是否是违反唯一性约束,是则通过f003v_0030定位该记录,获取记录id,该记录id会出现在发送方处理确认消息后的再确认消息中.再确认的目的是告诉接收方"我知道已经送达了",这时才可以安全地清理tb_0030的记录.

 

消除此错误的代码修改如下:(已修改gyb trunk和das)

(1)semq.h  

SaveAck增加dont_save参数,表示是否保存,如不保存则直接查询待确认记录.

class CSEMQ  : public ISEMQ,public IEventHandler,ACE_Event_Handler {  

public:
   static int SaveAck(SEMQ_ACK_HELPER *ak,short dont_save=0); 
 }
  
(2)semq.cpp   
int CSEMQ::SaveAck(SEMQ_ACK_HELPER *ak,short dont_save) {
 USEDBC(pdbor,ack_queue_dbc_.c_str());

 ITableHandler *th = CBasePlugInModule::db_helper_->NewTableHandler(pdbor,"tb_0030");
 AUTO_POINTER_NODECLARE(ITableHandler,th);

 pdbor->BeginTrans();
 unsigned short num = ak->loc_keys_.size();
 for (unsigned short i=0;i<num;i++) {
  MQ_LOC_KEY *lk = ak->loc_keys_[i];
  char key[128];
  sprintf(key,"%d,%d,%d,%d,%I64d",lk->node_type_,lk->node_id_,lk->mq_id_,lk->mq_db_id_,lk->record_id_);
  unsigned __int64 record_id;
  bool dup_key_error = false;

  if (!dont_save) {
   th->BindField("f003v_0030",key);
   char date[32];
   CDateTime::GetDateTime(date);
   th->BindField("src_type",(char**)&ak->src_.type_,sizeof(ak->src_.type_));
   th->BindField("src_id",(char**)&ak->src_.id_,sizeof(ak->src_.id_));
   th->BindField("dest_type",(char**)&ak->dest_.type_,sizeof(ak->dest_.type_));
   th->BindField("dest_id",(char**)&ak->dest_.id_,sizeof(ak->dest_.id_));
   th->BindField("f005d_0030",date);
   if (th->Insert()) {
    dup_key_error = pdbor->GetDBExt()->IsDuplicateKeyError(pdbor->GetLastErrorCode());
    if (!dup_key_error) {
     return -1;
    }
   }

   if (!dup_key_error) {
    if (pdbor->GetDBExt()->GetLastID(record_id,1,"tb_0030")) {
     return -2;
    }
   }
  }
  if (dont_save||dup_key_error) {
   string sql = LogMsg("select object_id from tb_0030 where f003v_0030='%s'",key);
   _variant_t v;
   if (QueryValue(pdbor,sql.c_str(),&v)) {
    return -3;
   }
   string sVal = ExVariantToString(v);
   record_id = a2Li(sVal.c_str());
  }
  ak->src_record_ids_.push_back(record_id); ///< 保存写入的待确认记录的记录编号
 }
 FAIL_RETURN(pdbor->CommitTrans(),,-1);

 return 0;
}
  
(3)router.cpp  
int CBBoxPlugin::HandleInput(CWrappedMsg<> *pwm,void **pploc,int &action)  {
 int ret = -1;
 try {
  CMsg *msg = pwm->GetMsg();
  bool do_ack = msg->IsAutoAck(); ///< 包含msg->IsAck2
  ret = HandleInput_i(pwm,pploc,action);
  nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_DEBUG,"************CBBoxPlugin::HandleInput_i()返回%d.\n",ret);
  /// ret: 0-交给插件处理 其它值:错误 (<0)或者转发(>0)
  SEMQ_ACK_HELPER *ah = (SEMQ_ACK_HELPER*)*pploc;
  if (action&&do_ack) {
   if (action==-1)
    semq_.Ack(ah,1);
   else {
    if (semq_.SaveAck(ah,action==3 ? 1:0)==0)
     semq_.Ack(ah,0);
   }
  }
  if (ret) { /// ret==0表示交给插件处理,其它值时释放ah对象
   if (ah) {
    delete ah;
    *pploc = 0;
   }
  }
 } catch(...) {
  nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"************CBBoxPlugin::HandleInput()异常.\n");
 }

 return ret;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wherwh/article/details/41848369

智能推荐

[常用办公软件] wps怎么自动生成目录?wps自动生成目录的设置教程_wps目录自动生成-程序员宅基地

文章浏览阅读1.1w次,点赞3次,收藏5次。转载请说明来源于"厦门SEO"本文地址:http://www.96096.cc/Article/160880.html常用办公软件  WPS Office是由金山软件股份有限公司开发的一款针对个人永久免费的办公软件,在我们的日常生活和工作中,WPS Office比起微软Microsoft Office来说在文字上的处理会更深入国人用户的人心,熟悉操作WPS的办公小技巧,能够更高效的提高我们的工作效率,今天小编要为大家分享的是WPS怎么自动生成目录?快来一起看看WPS自动生成目录的设置教程吧。_wps目录自动生成

web项目-程序员宅基地

文章浏览阅读7.4k次,点赞2次,收藏19次。web项目是指服务端部署在服务器上,客户端使用浏览器通过网络传输进行访问获取数据的项目。通常我们看见的应用页面网站等等都可以称之为web项目。 在web项目的开发中可分为web前端开发和web后端开发 web前端:即是客户端能看得见碰得着得东西。包括Web页面结构、页面样式外观以及Web层面得交互展现。 前端特点:页面视觉效果良好(客户第一)、Web页面交互流畅(..._web项目

关于java操作excel导入导出三种方式_java导出excel的三种方法-程序员宅基地

文章浏览阅读5.6k次,点赞8次,收藏67次。java操作关于导入导出Excel的多种方式_java导出excel的三种方法

Windows系统环境变量path详解_windows path-程序员宅基地

文章浏览阅读1.1w次,点赞10次,收藏21次。Windows path系统变量编辑_windows path

Hadoop基础教程-第13章 源码编译(13.2 Hadoop2.7.3源码编译)_hadoop2.7.3-src源码下载-程序员宅基地

文章浏览阅读512次。第13章 源码编译13.2 Hadoop2.7.3源码编译13.2.1下载Hadoop源码包(1)到官网http://hadoop.apache.org/releases.html下载2.7.3的source源码包(2)解压缩tar -zxvf hadoop-2.7.3-src.tar.gz -C /opt1(3)打开解压目录下的BUILDING.txt,编译过程和需要的软件其实就是根据这个文档里..._hadoop2.7.3-src源码下载

Latex 语法_\latex-程序员宅基地

文章浏览阅读1k次。Latex 语法_\latex

随便推点

【前端素材】推荐优质新鲜绿色蔬菜商城网站设计Harmic平台模板(附源码)-程序员宅基地

文章浏览阅读753次,点赞30次,收藏21次。在线绿色新鲜果蔬商店网站是指一个专门销售新鲜、绿色、有机水果和蔬菜的电子商务平台。这类网站旨在为消费者提供方便、快捷的购买渠道,同时确保他们能够购买到高质量、新鲜的产品。

elementui表格添加fixed之后样式异常_element table fixed 样式异常-程序员宅基地

文章浏览阅读1k次。最近写项目碰到一个bug 大概就是一个表格组件两个页面都会使用 组件中表格的某些列就用v-if控制了 表格的首尾列都用了fixed 然后就发生了bug 如下图 具体原因不明看过很多网上的办法 有在fixed的列绑定key的 也有使用doLayout()的 测了都没用 最后在一个前端交流群里一位大佬给出的办法 实测有效.el-table__header, .el-table__body, .el-table__footer { width: 100%; tab_element table fixed 样式异常

C语言中的 #include <stdio.h>是什么?_include <stdio.h>含义-程序员宅基地

文章浏览阅读1.8w次,点赞39次,收藏98次。最近在学习C语言基础的时候,我注意到了在写代码时经常使用的 #include <stdio.h>。众所周知,这是引用头文件的操作,但对于它的深层次含义,我并没有更多的了解。所以今天就来让我们深入研究一下它的更多信息。include的意思是包含,它前面的 # 是预处理指令。#通常有三种功能:1. 宏定义 2 .文件包含 3.条件编译。例如#define定义的标识符常量,这就属于一种宏定义的用法。其他的用法,随着深入学习相信也都会接触到。<stdio.h>就是我们引用的头文件,相_include 含义

(转载)linux命令之五十三telnet命令_telnet linux reboot-程序员宅基地

文章浏览阅读722次。telnet命令通常用来远程登录。telnet程序是基于TELNET协议的远程登录客户端程序。Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的 能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台_telnet linux reboot

局部色调映射(Local Tone Mapping)-程序员宅基地

文章浏览阅读5k次。重建视觉外观是色调映射的终极目标。色调映射算法在降低高动态图像(HDR)范围的同时着力保护捕捉到的原始图像的外观。色调映射算子分两种策略,一种是全局的,另一种是局部的。1. 全局映射算子每一个像素点将会根据它的全图特征和亮度信息进行映射,不管其空间位置几何。全局算子一个比较典型的例子就是色调曲线。全局色调映射在处理12位(12-bit)深度的图像的时候是完全OK的,当图像的动态范围特别高的时候,那就不行了。这是因为所有的像素点都采取同一种方式进行处理,根本就没有管它是在较亮区域还是较暗区域。这样的话,._local tone mapping

RadioButton、CheckBox与ToggleButton-程序员宅基地

文章浏览阅读86次。1.RadioButtonRadioButton被称作为单选框,通常都是以组的形式出现,可以在一组控件中选择一个。RadioButton的使用首先需要加入<RadioGroup/>,在这个组中,我们进行单选按钮的声明。 1 <RadioGroup 2 android:id="@+id/radioGroup" 3 an..._radiobutton和toggombutton