WxAdoPool.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #include "StdAfx.h"
  2. #include "WxAdoPool.h"
  3. #include "Global.h"
  4. //////////////////////////////////////////////////////////////////////////
  5. CWxAdoPool::CWxAdoPool()
  6. {
  7. m_nRef = 0;
  8. m_nObjRef = 0;
  9. m_nMaxCount = 0;
  10. m_nMinCount = 0;
  11. m_bNeedExit = FALSE;
  12. m_bNeedStop = FALSE;
  13. m_bNeedConnection = FALSE;
  14. }
  15. CWxAdoPool::~CWxAdoPool()
  16. {
  17. m_strDBAccount.Empty();
  18. m_strDBName.Empty();
  19. m_strDBSource.Empty();
  20. m_strPassWord.Empty();
  21. DestroyAllDBConnections();
  22. }
  23. DWORD CWxAdoPool::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 */)
  24. {
  25. if ( !lpDBSource || lpDBSource[0] == _T('\0') || !lpDBName || lpDBName[0] == _T('\0') )
  26. {
  27. return 0;
  28. }
  29. m_strDBSource = lpDBSource;
  30. m_dwDBPort = dwDBPort;
  31. m_strDBAccount = lpDBAccount;
  32. m_strPassWord = lpPassWord;
  33. m_strDBName = lpDBName;
  34. m_nMinCount = nMinConn;
  35. m_nMaxCount = nMaxConn;
  36. return IntiAllConnections();
  37. }
  38. void CWxAdoPool::ReleasePool()
  39. {
  40. DestroyAllDBConnections();
  41. }
  42. INT CWxAdoPool::IntiAllConnections()
  43. {
  44. DestroyAllDBConnections();
  45. #if USE_ODBC
  46. // 开始按照最小数量开始创建;
  47. int nCount = 0;
  48. CDatabase *pDatabase = NULL;
  49. for (int i = 0; i < m_nMinCount; i++)
  50. {
  51. pDatabase = InitAConnection();
  52. if ( pDatabase )
  53. {
  54. nCount++;
  55. m_listIdleConnections._push_back(pDatabase);
  56. InterlockedIncrement(&m_nObjRef); //增加引用计数;
  57. pDatabase = NULL;
  58. }
  59. }
  60. #else
  61. int nCount = 0;
  62. pAdoObj pDatabase = NULL;
  63. for ( int i = 0; i < m_nMinCount; i++)
  64. {
  65. pDatabase = InitAConnection();
  66. if (pDatabase)
  67. {
  68. nCount++;
  69. m_listIdleConnections._push_back(pDatabase);
  70. InterlockedIncrement(&m_nObjRef);
  71. pDatabase = NULL;
  72. }
  73. }
  74. #endif
  75. return nCount;
  76. }
  77. void CWxAdoPool::DestroyAllDBConnections()
  78. {
  79. m_bNeedExit = TRUE;
  80. // 首先等待m_listBusyConnections.size() == 0;
  81. while(1)
  82. {
  83. if ( m_listBusyConnections.size() == 0 )
  84. break;
  85. Sleep(1000);
  86. }
  87. pAdoObj pObj = NULL;
  88. AdoConnList::iterator itIdle = m_listIdleConnections.begin();
  89. while (itIdle != m_listIdleConnections.end())
  90. {
  91. pObj = *itIdle;
  92. if (NULL != pObj)
  93. {
  94. //if (pObj->pConnection)
  95. //{
  96. // pObj->pConnection->Close();
  97. // pObj->pConnection->Release();
  98. //}
  99. //if (pObj->pCommand)
  100. //{
  101. // pObj->pCommand->Release();
  102. //}
  103. //if (pObj->pRecordSet)
  104. // pObj->pRecordSet.Release();
  105. #ifdef _DEBUG
  106. OutputDebugString(_T("删除连接池对象\n"));
  107. #endif
  108. delete pObj;
  109. pObj = NULL;
  110. }
  111. itIdle = m_listIdleConnections.erase(itIdle);
  112. }
  113. m_bNeedExit = FALSE;
  114. }
  115. pAdoObj CWxAdoPool::GetAConnection( IN CONST DWORD &dwTimeOut /* = 1000 */ )
  116. {
  117. if ( m_bNeedExit )// 停止获取;
  118. return NULL;
  119. // 1.首先到池中查找有无空闲对象;
  120. BOOL bGetIdl = FALSE;
  121. DWORD dwTime = GetTickCount();
  122. pAdoObj pConnection = NULL;
  123. do
  124. {
  125. if ( m_listIdleConnections._size() > 0){
  126. //AutoThreadSection aSection(&m_critSection);
  127. pConnection = m_listIdleConnections._pop_front_();
  128. if (pConnection)
  129. {
  130. m_listBusyConnections._push_back(pConnection);
  131. bGetIdl = TRUE;
  132. }
  133. }
  134. else
  135. {
  136. if (m_nObjRef < m_nMaxCount)
  137. {
  138. //AutoThreadSection aSection(&m_critSection);
  139. pConnection = InitAConnection();
  140. if (pConnection){
  141. //bGetIdl = TRUE;
  142. m_listBusyConnections._push_back(pConnection);
  143. InterlockedIncrement(&m_nObjRef); //增加引用计数;
  144. Global::WriteTextLog(_T("创建连接对象:共有 %d 个"), m_nObjRef);
  145. break;
  146. }
  147. }
  148. }
  149. if ( !bGetIdl ) {
  150. // 未找到,小憩一会,防止CPU爆满;
  151. Sleep(0);
  152. // 超时,则结束返回NULL;
  153. if ( (GetTickCount() - dwTime) >= dwTimeOut){
  154. Global::WriteTextLog(_T("获取连接对象超时"));
  155. break;
  156. }
  157. }
  158. } while ( !bGetIdl );
  159. return pConnection;
  160. }
  161. void CWxAdoPool::RestoreAConnection(IN pAdoObj pObj)
  162. {
  163. if (pObj != NULL ){
  164. m_listBusyConnections._remove(pObj);
  165. if (pObj->pConnection->GetState() != adStateClosed)
  166. m_listIdleConnections._push_back(pObj);
  167. else
  168. delete pObj;
  169. }
  170. }
  171. pAdoObj CWxAdoPool::InitAConnection()
  172. {
  173. if ( m_nObjRef == m_nMaxCount )
  174. return NULL;
  175. pAdoObj pObj = new AdoObj;
  176. pObj->pConnection.CreateInstance(__uuidof(Connection));
  177. TCHAR szConnString[MAX_PATH] = {0};
  178. if (m_dwDBPort != 0)
  179. {
  180. if ( m_strDBAccount.IsEmpty() )
  181. _stprintf_s(szConnString, MAX_PATH, DB_SW_CONN_WITH_PORT, m_strDBSource, m_dwDBPort,m_strDBName);
  182. else
  183. _stprintf_s(szConnString, MAX_PATH, DB_SS_CONN_WITH_PORT,m_strDBSource, m_dwDBPort, m_strDBName, m_strDBAccount, m_strPassWord);
  184. }
  185. else
  186. {
  187. if ( m_strDBAccount.IsEmpty() )
  188. _stprintf_s(szConnString, MAX_PATH, DB_SW_CONN_WITHOUT_PORT, m_strDBSource, m_strDBName);
  189. else
  190. _stprintf_s(szConnString, MAX_PATH, DB_SS_CONN_WITHOUT_PORT, m_strDBSource, m_strDBName, m_strDBAccount, m_strPassWord);
  191. }
  192. try
  193. {
  194. HRESULT hr = pObj->pConnection->Open(_bstr_t(szConnString), "", "", adModeUnknown);
  195. if (FAILED(hr))
  196. {
  197. if (pObj)
  198. delete pObj;
  199. pObj = NULL;
  200. return NULL;
  201. }
  202. pObj->pCommand.CreateInstance(__uuidof(Command));
  203. // 将库连接赋于它;
  204. pObj->pCommand->ActiveConnection = pObj->pConnection;
  205. }
  206. catch (_com_error &e)
  207. {
  208. _bstr_t bstrSource(e.Source());
  209. _bstr_t bstrDescription(e.Description());
  210. if (pObj)
  211. delete pObj;
  212. pObj = NULL;
  213. Global::WriteTextLog(_T("SQL连接串:%08lx,%s,%s,%s"), e.Error(), e.ErrorMessage(), (TCHAR*)bstrSource, (TCHAR*)bstrDescription);
  214. }
  215. return pObj;
  216. }
  217. void CWxAdoPool::CloseAConnection(pAdoObj &pDataBase)
  218. {
  219. m_listIdleConnections._remove(pDataBase);
  220. InterlockedDecrement(&m_nObjRef); // 减少计数;
  221. if ( pDataBase )
  222. delete pDataBase;
  223. pDataBase = NULL;
  224. }
  225. void CWxAdoPool::CloseBusyConnection(IN pAdoObj &pDataBase)
  226. {
  227. m_listBusyConnections._remove(pDataBase);
  228. InterlockedDecrement(&m_nObjRef); // 减少计数;
  229. if ( pDataBase )
  230. pDataBase->pConnection->Close();
  231. }