WxAdoPool.cpp 5.5 KB

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