3、使用连接池管理连接.
在有大量节点访问的数据库设计中,经常要使用到连接池来管理所有的连接. 一般方法是:建立两个连接句柄队列,空闲的等待使用的队列和正在使用的队列. 当要查询时先从空闲队列中获取一个句柄,插入到正在使用的队列,再用这个句柄做数据库操作,完毕后一定要从使用队列中删除,再插入到空闲队列.
设计代码如下:
//定义句柄队列 typedef std::list<MYSQL *> CONNECTION_HANDLE_LIST; typedef std::list<MYSQL *>::iterator CONNECTION_HANDLE_LIST_IT; //连接数据库的参数结构 class CDBParameter { public: char *host; ///<主机名 char *user; ///<用户名 char *password; ///<密码 char *database; ///<数据库名 unsigned int port; ///<端口,一般为0 const char *unix_socket; ///<套接字,一般为NULL unsigned int client_flag; ///<一般为0 }; //创建两个队列 CONNECTION_HANDLE_LIST m_lsBusyList; ///<正在使用的连接句柄 CONNECTION_HANDLE_LIST m_lsIdleList; ///<未使用的连接句柄 //所有的连接句柄先连上数据库,加入到空闲队列中,等待使用. bool CDBManager::Connect(char * host /* = "localhost" */, char * user /* = "chenmin" */, \ char * password /* = "chenmin" */, char * database /* = "HostCache" */) { CDBParameter * lpDBParam = new CDBParameter(); lpDBParam->host = host; lpDBParam->user = user; lpDBParam->password = password; lpDBParam->database = database; lpDBParam->port = 0; lpDBParam->unix_socket = NULL; lpDBParam->client_flag = 0; try { //连接 for(int index = 0; index < CONNECTION_NUM; index++) { MYSQL * pConnectHandle = mysql_init((MYSQL*) 0); //初始化连接句柄 if(!mysql_real_connect(pConnectHandle, lpDBParam->host, lpDBParam->user, lpDBParam->password,\ lpDBParam->database,lpDBParam->port,lpDBParam->unix_socket,lpDBParam->client_fla)) return false; //加入到空闲队列中 m_lsIdleList.push_back(pConnectHandle); } } catch(...) { return false; } return true; } //提取一个空闲句柄供使用 MYSQL * CDBManager::GetIdleConnectHandle() { MYSQL * pConnectHandle = NULL; m_ListMutex.acquire(); if(m_lsIdleList.size()) { pConnectHandle = m_lsIdleList.front(); m_lsIdleList.pop_front(); m_lsBusyList.push_back(pConnectHandle); } else //特殊情况,闲队列中为空,返回为空 { pConnectHandle = 0; } m_ListMutex.release(); return pConnectHandle; } //从使用队列中释放一个使用完毕的句柄,插入到空闲队列 void CDBManager::SetIdleConnectHandle(MYSQL * connecthandle) { m_ListMutex.acquire(); m_lsBusyList.remove(connecthandle); m_lsIdleList.push_back(connecthandle); m_ListMutex.release(); } //使用示例,首先获取空闲句柄,利用这个句柄做真正的操作,然后再插回到空闲队列 bool CDBManager::DeleteHostCacheBySessionID(char * sessionid) { MYSQL * pConnectHandle = GetIdleConnectHandle(); if(!pConnectHandle) return 0; bool bRet = DeleteHostCacheBySessionID(pConnectHandle, sessionid); SetIdleConnectHandle(pConnectHandle); return bRet; } //传入空闲的句柄,做真正的删除操作 bool CDBManager::DeleteHostCacheBySessionID(MYSQL * connecthandle, char * sessionid) { char deleteSQL[SQL_LENGTH]; memset(deleteSQL, 0, sizeof(deleteSQL)); sprintf(deleteSQL,"delete from HostCache where SessionID = '%s'", sessionid); if(mysql_query(connecthandle,deleteSQL) != 0) //删除 return false; return true; }
(责任编辑:admin) |