3、使用連接池管理連接.
在有大量節(jié)點訪問的數(shù)據(jù)庫設(shè)計中,經(jīng)常要使用到連接池來管理所有的連接. 一般方法是:建立兩個連接句柄隊列,空閑的等待使用的隊列和正在使用的隊列. 當(dāng)要查詢時先從空閑隊列中獲取一個句柄,插入到正在使用的隊列,再用這個句柄做數(shù)據(jù)庫操作,完畢后一定要從使用隊列中刪除,再插入到空閑隊列.
設(shè)計代碼如下:
//定義句柄隊列 typedef std::list<MYSQL *> CONNECTION_HANDLE_LIST; typedef std::list<MYSQL *>::iterator CONNECTION_HANDLE_LIST_IT; //連接數(shù)據(jù)庫的參數(shù)結(jié)構(gòu) class CDBParameter { public: char *host; ///<主機(jī)名 char *user; ///<用戶名 char *password; ///<密碼 char *database; ///<數(shù)據(jù)庫名 unsigned int port; ///<端口,一般為0 const char *unix_socket; ///<套接字,一般為NULL unsigned int client_flag; ///<一般為0 }; //創(chuàng)建兩個隊列 CONNECTION_HANDLE_LIST m_lsBusyList; ///<正在使用的連接句柄 CONNECTION_HANDLE_LIST m_lsIdleList; ///<未使用的連接句柄 //所有的連接句柄先連上數(shù)據(jù)庫,加入到空閑隊列中,等待使用. 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; }
本文鏈接:http://www.95time.cn/tech/program/2009/6391.asp
出處:陳敏的Blog
責(zé)任編輯:bluehearts
上一頁 提高M(jìn)ySQL查詢效率的三個技巧 [2] 下一頁
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|