#include "StdAfx.h" #include "dbpool.h" #include "Global.h" ////////////////////////////////////////////////////////////////////////// CODBCPool::CODBCPool() { m_nRef = 0; m_nObjRef = 0; m_nMaxCount = 0; m_nMinCount = 0; m_bNeedExit = FALSE; m_bNeedStop = FALSE; m_bNeedConnection = FALSE; } CODBCPool::~CODBCPool() { DestroyAllDBConnections(); } DWORD CODBCPool::InitializePool(IN LPCTSTR lpDBSource, IN CONST DWORD &dwDBPort, IN LPCTSTR lpDBAccount, IN LPCTSTR lpPassWord, IN LPCTSTR lpDBName, IN CONST INT &nMinConn /* = 1 */, IN CONST INT &nMaxConn /* = 5 */) { if ( !lpDBSource || lpDBSource[0] == _T('\0') || !lpDBName || lpDBName[0] == _T('\0') ) { return 0; } m_strDBSource = lpDBSource; m_dwDBPort = dwDBPort; m_strDBAccount = lpDBAccount; m_strPassWord = lpPassWord; m_strDBName = lpDBName; m_nMinCount = nMinConn; m_nMaxCount = nMaxConn; return IntiAllConnections(); } void CODBCPool::ReleasePool() { DestroyAllDBConnections(); } INT CODBCPool::IntiAllConnections() { DestroyAllDBConnections(); // 开始按照最小数量开始创建; int nCount = 0; CDatabase *pDatabase = NULL; for (int i = 0; i < m_nMinCount; i++) { pDatabase = InitAConnection(); if ( pDatabase ) { nCount++; m_listIdleConnections._push_back(pDatabase); InterlockedIncrement(&m_nObjRef); //增加引用计数; pDatabase = NULL; } } return nCount; } void CODBCPool::DestroyAllDBConnections() { m_bNeedExit = TRUE; // 首先等待m_listBusyConnections.size() == 0; while(1) { if ( m_listBusyConnections.size() == 0 ) break; Sleep(1000); } ODBCConnectList::iterator itIdle = m_listIdleConnections.begin(); while (itIdle != m_listIdleConnections.end()) { if (NULL != (*itIdle)) { (*itIdle)->Close(); delete (*itIdle); } itIdle = m_listIdleConnections.erase(itIdle); } m_bNeedExit = FALSE; } CDatabase* CODBCPool::GetAConnection( IN CONST DWORD &dwTimeOut /* = 1000 */ ) { if ( m_bNeedExit )// 停止获取; return NULL; // 1.首先到池中查找有无空闲对象; BOOL bGetIdl = FALSE; DWORD dwTime = GetTickCount(); CDatabase* pDBEngine = NULL; do { if ( m_listIdleConnections._size() > 0){ //AutoThreadSection aSection(&m_critSection); pDBEngine = m_listIdleConnections._pop_front_(); if (pDBEngine) { m_listBusyConnections._push_back(pDBEngine); bGetIdl = TRUE; } } else { if (m_nObjRef < m_nMaxCount) { //AutoThreadSection aSection(&m_critSection); pDBEngine = InitAConnection(); if (pDBEngine){ //bGetIdl = TRUE; m_listBusyConnections._push_back(pDBEngine); InterlockedIncrement(&m_nObjRef); //增加引用计数; Global::WriteTextLog(_T("创建连接对象:共有 %d 个"), m_nObjRef); break; } } } if ( !bGetIdl ) { // 未找到,小憩一会,防止CPU爆满; Sleep(0); // 超时,则结束返回NULL; if ( (GetTickCount() - dwTime) >= dwTimeOut){ Global::WriteTextLog(_T("获取连接对象超时")); break; } } } while ( !bGetIdl ); return pDBEngine; } void CODBCPool::RestoreAConnection(IN CDatabase *pDBEngine) { if ( pDBEngine != NULL ){ m_listBusyConnections._remove(pDBEngine); if ( pDBEngine->IsOpen() ) m_listIdleConnections._push_back(pDBEngine); else delete pDBEngine; } } CDatabase* CODBCPool::InitAConnection() { if ( m_nObjRef == m_nMaxCount ) return NULL; CDatabase * pDBEngine = new CDatabase; TCHAR szConnString[MAX_PATH] = {0}; if (m_dwDBPort != 0) { if ( m_strDBAccount.IsEmpty() ) _stprintf_s(szConnString, MAX_PATH, DB_SW_CONN_WITH_PORT, m_strDBSource, m_dwDBPort,m_strDBName); else _stprintf_s(szConnString, MAX_PATH, DB_SS_CONN_WITH_PORT,m_strDBSource, m_dwDBPort, m_strDBName, m_strDBAccount, m_strPassWord); } else { if ( m_strDBAccount.IsEmpty() ) _stprintf_s(szConnString, MAX_PATH, DB_SW_CONN_WITHOUT_PORT, m_strDBSource, m_strDBName); else _stprintf_s(szConnString, MAX_PATH, DB_SS_CONN_WITHOUT_PORT, m_strDBSource, m_strDBName, m_strDBAccount, m_strPassWord); } try { pDBEngine->OpenEx(szConnString, CDatabase::noOdbcDialog); } catch (CDBException* e) { if ( pDBEngine ) delete pDBEngine; pDBEngine = NULL; Global::WriteTextLog(_T("SQL连接串:%s, 返回错误:%s"), szConnString, e->m_strError); } return pDBEngine; } void CODBCPool::CloseAConnection(CDatabase *&pDataBase) { m_listIdleConnections._remove(pDataBase); InterlockedDecrement(&m_nObjRef); // 减少计数; if ( pDataBase ) delete pDataBase; pDataBase = NULL; } void CODBCPool::CloseBusyConnection(IN CDatabase *&pDataBase) { m_listBusyConnections._remove(pDataBase); InterlockedDecrement(&m_nObjRef); // 减少计数; if ( pDataBase ) pDataBase->Close(); }