多线程访问ado数据库问题
我只建了一个连接m_pConnection
void CADOConn::OnInitADOConn()
{
CoInitialize(NULL);
try
{
if (m_pConnection==NULL)
{
m_pConnection.CreateInstance("ADODB.Connection");
_bstr_t strConnect="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;PWD=123456;Initial Catalog=secsys; Data Source=FSJ";
m_pConnection->Open(strConnect,"","",adModeUnknown);
}
}}
然后用多线程访问数据库,当用多线程批量插入数据时,出现了错误。
请高手指教,
如何处理这样的问题?
要过年了我还想早点回家,望高手帮助我尽快解决问题啊!
[解决办法]
在操作数据库的时候加个缩,操作完后打开锁
[解决办法]
事务,
- C/C++ code
/*######################################################################## ------------------------------------------------ 事务处理 ------------------------------------------------ ########################################################################*//*======================================================================== Name: 开始新事务. ----------------------------------------------------- returns: 对于支持嵌套事务的数据库来说, 在已打开的事务中调用 BeginTrans 方法将开始新的嵌套事务. 返回值将指示嵌套层次: 返回值为 1 表示已打开顶层 事务 (即事务不被另一个事务所嵌套), 返回值为 2 表示已打开第二层事务(嵌套 在顶层事务中的事务), 依次类推. ----------------------------------------------------- Remarks: 一旦调用了 BeginTrans 方法, 在调用 CommitTrans 或 RollbackTrans 结束事务之前, 数据库将不再立即提交所作的任何更改. ==========================================================================*/long CAdoConnection::BeginTrans(){ ASSERT(m_pConnection != NULL); try { return m_pConnection->BeginTrans(); } catch (_com_error e) { TRACE(_T("Warning: BeginTrans 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__); return -1; } return -1;}/*======================================================================== Name: 保存任何更改并结束当前事务. ----------------------------------------------------- Remarks: 调用 CommitTrans 或 RollbackTrans 只影响最新打开的事务; 在 处理任何更高层事务之前必须关闭或回卷当前事务.==========================================================================*/BOOL CAdoConnection::CommitTrans(){ ASSERT(m_pConnection != NULL); try { return SUCCEEDED(m_pConnection->CommitTrans()); } catch (_com_error e) { TRACE(_T("Warning: CommitTrans 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__); return FALSE; } return FALSE;}/*======================================================================== Name: 取消当前事务中所作的任何更改并结束事务.==========================================================================*/BOOL CAdoConnection::RollbackTrans(){ ASSERT(m_pConnection != NULL); try { return SUCCEEDED(m_pConnection->RollbackTrans()); } catch (_com_error e) { TRACE(_T("Warning: RollbackTrans 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__); return FALSE; } return FALSE;}
[解决办法]
为什么要用多线程插入数据
你是如何用的
[解决办法]
ado是基于COM的,连接也是COM接口,而COM接口跨线程使用时必须列集散列。
- C/C++ code
IStream* m_pStream = NULL; // 全局变量,多线程共同使用// 主线程CoMarshalInterThreadInterfaceInStream(__uuidof(_Connection), m_pConnection.GetInterface(), &m_pStream);// 子线程_ConnectionPtr pConn;CoGetInterfaceAndReleaseStream(m_pStream, __uuidof(_Connection), &pConn);// 现在可以使用pConn了
[解决办法]
你多线程是操作的同一连接,同一记录集吗?
[解决办法]
对于SqlServer,建议:
1.使用明式事务(数据库不可能没有任何索引);
2.批量Insert(多条语句中间使用分号分隔开);
3.线程内建立连接,或者使用连接池,线程初始化时,将CoInitialize(NULL)改为CoInitializeEx(NULL, COINIT_MULTITHREADED)。
[解决办法]
我出现过类此错误,当时catch一下,发现是“没有活动事务”,估计你也是,另外insert语句,最好放在try中