IDbHelper接口NewTableHandler实现增强

来源:互联网 发布:apple mac mini 编辑:程序博客网 时间:2024/04/30 11:24

某托管服务器崩溃产生了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>


 

0 0
原创粉丝点击