IDbHelper接口NewTableHandler实现增强

某托管服务器崩溃产生了crash,经惠礼分析定位到missive插件中处理消息执行下面的调用时返回NULL,后续对th的访问导致崩溃:
ITableHandler *th = CBasePluginModule::db_helper_->NewTableHandler(pdbor,"tb_6016");

使用IDbHelper接口NewTableHandler创建表处理器对象,用来操纵数据库.避免编写SQL.

  GETDBC(pdbor,this->local_dbc_.c_str());
  ITableHandler *th = CBasePluginModule::db_helper_->NewTableHandler(pdbor,"tb_6016");
  AUTO_POINTER_NODECLARE(ITableHandler,th);
  th->BindField("missive_id",(char*)strmissive_id.c_str(),0);
  th->BindField("missive_name",(char*)strmissive_name.c_str(),0);

  
NewTableHandler实现代码如下:

ITableHandler* HTX_DB_Helper::NewTableHandler(CDbAccessor *pdbor,const char *tbl_name) { 
 CTableInfo *tbl;
 string s = StringToUpper(tbl_name);
 tbl = this->FindTable(s.c_str());
 if (tbl==NULL)
  tbl = this->OpenTable(pdbor,s.c_str());
 CTableHandler *th = 0;
 if (tbl) {
  th = new CTableHandler;
  th->Attach(tbl);
  th->SetDbAccessor(pdbor);
 }
 return th; 
} 


在执行OpenTable时,如果出现数据库访问故障(如网络或者数据库系统原因),就可能导致返回的th为NULL.

此问题以前从发现过。采用的方式是在服务器启动时预先执行,初始化后再出现数据库访问故障不会导致问题,,因为表的模式信息已被缓存。
如bbox插件的处理如下:

int CBBoxPlugin::CheckValid()
{
 parent::CheckValid();

 InitTableHandler("tb_0032");
 InitTableHandler(REDO_TABLE_NAME);

 return 0;
}

int CBBoxPlugin::InitTableHandler(const char *tbl_name) {
 do { 
  GETDBC(pdbor,this->local_dbc_.c_str());
  ITableHandler *th = db_helper_->NewTableHandler(pdbor,tbl_name);
  AUTO_POINTER_NODECLARE(ITableHandler,th);
  if (th)
   break;
  ACE_OS::sleep(1);
 }while(1);

 return 0;
}

 

以上是一种处理问题的方法。
更简单和彻底的解决办法是修改NewTableHandler的实现,升级hotfox。
修改后的代码如下:

<p>ITableHandler* HTX_DB_Helper::NewTableHandler(CDbAccessor *pdbor,const char *tbl_name) { 
 CTableInfo *tbl;
 string s = StringToUpper(tbl_name);
 tbl = this->FindTable(s.c_str());
 if (tbl==NULL) {
  CDbAccessor2 *p = dynamic_cast<CDbAccessor2*>(pdbor);
  const char *dbc_name = p->GetPool()->dbcc_->name.c_str();
  do {
   CDbAccessor *new_pdbor = HTX_DBPOOL::instance()->GetDbConnection(dbc_name,-1,true,true);
   tbl = this->OpenTable(new_pdbor,s.c_str());
   HTX_DBPOOL::instance()->ReleaseDbConnection(new_pdbor);
  }while(tbl==0);
 }
 CTableHandler *th = 0;
 if (tbl) {
  th = new CTableHandler;
  th->Attach(tbl);
  th->SetDbAccessor(pdbor);
 }</p><p> return th; 
}</p>


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值