日期:2014-05-16 浏览次数:20389 次
先描述一下我的问题
公司开发一套新的打印服务,其中有多个线程可能同时对数据库进行访问,开始的时候用的是一个数据库连接,但是在多个线程同时访问的时候会报数据库异步访问和一些com异常,之后查阅了一些资料,发现在利用ado在进行多线程的数据库访问的时候,最好每个线程对应一个数据库连接,为了方便对这些链接进行管理,自己写了一个数据库连接池,将源码放到这里和大家分享,共同进步,希望能解决一些各位遇到的问题
#pragma once
class DBConnPool
{
private:
std::map<DWORD, CADODatabase*> m_DbConns;//一个线程对应一个数据库连接的指针
CComAutoCriticalSection m_SyncRoot;
public:
CString m_strConn;//数据库连接串
public:
//DBConnPool(void)
//{
//}
DBConnPool(void)
{
}
~DBConnPool(void)
{
Close();
}
private:
BOOL InitDB(CADODatabase* pDbConn)
{
if(!pDbConn->Open(m_strConn))
{
g_Log.Error("链接数据库失败,请检查连接或配置信息, connstr: %s, func: %s, at: %s(%d)",
(LPCTSTR)m_strConn, __FUNCTION__, __FILE__, __LINE__);
return FALSE;
}
return TRUE;
}
void CloseDB(CADODatabase* pDbConn)
{
if(pDbConn != 0)
{
if (pDbConn->IsOpen())
{
pDbConn->Close();
}
delete pDbConn;
pDbConn = 0;
}
}
public:
//BOOL Init(CString strDbConn)
//{
// m_strConn = strDbConn;
// if ("" != m_strConn)
// {
// return TRUE;
// }
// return FALSE;
//}
CADODatabase* GetDbConn()
{
ATL::CComCritSecLock<CComAutoCriticalSection> lck(m_SyncRoot);
DWORD dwThreadID = GetCurrentThreadId();
std::map<DWORD, CADODatabase*> ::iterator it = m_DbConns.find(dwThreadID);
if (it == m_DbConns.end())
{
CADODatabase* pDbConn = new CADODatabase();
if (InitDB(pDbConn))
{
m_DbConns.insert(std::map<DWORD, CADODatabase*>::value_type (dwThreadID,pDbConn));
return pDbConn;
}
return NULL;
}
else
{
return ((*it).second);
}
}
void Close()
{
ATL::CComCritSecLock<CComAutoCriticalSection> lck(m_SyncRoot);
std::map<DWORD, CADODatabase*> ::iterator it = m_DbConns.begin();
for(;it != m_DbConns.end(); ++it)
{
CloseDB((*it).second);
}
}
};