100分询问多线程调用ADO的问题

czg516 2006-01-10 02:23:09
我封装的ADO类ADOConn
class ADOConn
{
public:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
public:
ADOConn(){::CoInitialize(NULL);m_pConnection=NULL;m_pRecordset=NULL;}
virtual ~ADOConn(){::CoUninitialize();}
int DefaultConn();//建立连接m_pConnection;
void ExitConnect(){
if (NULL != m_pRecordset)
if (m_pRecordset->State)
m_pRecordset->Close();
if (NULL != m_pConnection)
if (m_pConnection->State)
m_pConnection->Close();
}
};


我在有一个线程需要时时检测数据库数据,我在线程里用的是下面的代码
while(1)
{
Sleep(1000);
ADOConn adoconn;
adoconn.DefaultConn();
........//一些数据删除,修改,查询的操作.
adoconn.ExitConnect();
}
//上面的代码可以运行一段时间,时间不固定,长时10分,短时3分,就报一个0xc0000005 Asscess violation的错误,
...全文
206 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
czg516 2006-01-10
  • 打赏
  • 举报
回复
谢谢,各位,结贴.
czg516 2006-01-10
  • 打赏
  • 举报
回复
希望各位大哥为我出些良策,小第一定另开帖为各位加分.
ndy_w 2006-01-10
  • 打赏
  • 举报
回复
加CriticalSection,或每个线程用一个连接。
czg516 2006-01-10
  • 打赏
  • 举报
回复
TO lzzqqq(Jonersen) ,handsomerun(毛毛)
用Release后,第一个循环就抱了错,追到代码里面去,发现是在析构adoconn时,代码内部已经调用了_release(),
所以我觉得这里的问题不是release()的问题,
有可能是lzzqqq(Jonersen)大哥说的数据库连接还没来的及断开就进入下个循环了,
我接着这样试下.

while(1)
{
ADOConn adoconn;
adoconn.DefaultConn();
........//一些数据删除,修改,查询的操作.
adoconn.ExitConnect
Sleep(3000);
}
czg516 2006-01-10
  • 打赏
  • 举报
回复
TO lzzqqq(Jonersen)
ADOConn adoconn;
adoconn.DefaultConn();
while(1)
{
........//一些数据删除,修改,查询的操作.
}
adoconn.ExitConnect();


用这种方法运行了40分,没有出现问题,但感觉治标没治本,
放在循环内部怎么做才能不报错处理,我想只有解决了这个问题,才会让我认识问题的本质.

我接着试下楼上的这个方法
void ExitConnect()
{
if (NULL != m_pRecordset)
{
m_pRecordset->Close();
m_pRecordset->Release();
m_pRecordset=NULL;
}
if (NULL != m_pConnection)
{
m_pConnection->Close();
m_pConnection->Release();
m_pConnection=NULL;
}
}
handsomerun 2006-01-10
  • 打赏
  • 举报
回复
要的
一个createinstance
对应一个release
lzzqqq 2006-01-10
  • 打赏
  • 举报
回复
看样子没有太耗时的数据库操作,应该没什么大问题啊,你按上面说的把COM指针Realease一下试试.不行再说.
void ExitConnect()
{
if (NULL != m_pRecordset)
{
m_pRecordset->Close();
m_pRecordset->Release();
m_pRecordset=NULL;
}
if (NULL != m_pConnection)
{
m_pConnection->Close();
m_pConnection->Release();
m_pConnection=NULL;
}
}
czg516 2006-01-10
  • 打赏
  • 举报
回复
TO handsomerun(毛毛)
智能指针需要release吗??/我印象中好象不需要.

createinstance已经被封装在类函数里头了.比如:DefaultConn(),(建立连接)
GetRecordSet()(执行select语句,并把得到记录交给m_pRecordset
czg516 2006-01-10
  • 打赏
  • 举报
回复
TO handsomerun(毛毛)
智能指针需要release吗??/我印象中好象不需要.

createinstance已经被封装在类函数里头了.比如:DefaultConn(),(建立连接)
GetRecordSet()(执行select语句,并把得到记录交给m_pRecordset)等函数.
handsomerun 2006-01-10
  • 打赏
  • 举报
回复
怎么在你的类里面没看到createinstance这样的代码
你用了吗??

还有release也没有看到??

这些都是需要的
czg516 2006-01-10
  • 打赏
  • 举报
回复
还有一个潜在的问题就是
........//一些数据删除,修改,查询的操作.
如果你这个过程比较长,比如里面有存储过程的调用等耗时操作.可能会在这个操作没完成之前就进入到下一个循环.从而造成数据库连接数过多或数据库死锁等问题.

TO:lzzqqq(Jonersen)
我这里面暂时涉及到的是查询一条记录,判断此记录状态,如果不符合要求,UPDATE一下,
这些操作会有你说的那个潜在的问题么????
Kudeet 2006-01-10
  • 打赏
  • 举报
回复
only DAO
http://www.codeproject.com/database/mtdaorecordset.asp
czg516 2006-01-10
  • 打赏
  • 举报
回复
好,谢谢,楼上的,我现在就试试.
lzzqqq 2006-01-10
  • 打赏
  • 举报
回复
还有,把你上面这个线程函数优化一下,不用每次都连接,关闭数据库,这样也可以减轻数据库的压力,有可能你操作数据库的时间还不如连接和释放数据库时间长.

ADOConn adoconn;
adoconn.DefaultConn();
while(1)
{
........//一些数据删除,修改,查询的操作.
}
adoconn.ExitConnect();
lzzqqq 2006-01-10
  • 打赏
  • 举报
回复
void ExitConnect(){
if (NULL != m_pRecordset)
{
m_pRecordset->Close();
pRecordset=NULL;
}
if (NULL != m_pConnection)
{
m_pConnection->Close();
pConnection=NULL;
}
还有一个潜在的问题就是
........//一些数据删除,修改,查询的操作.
如果你这个过程比较长,比如里面有存储过程的调用等耗时操作.可能会在这个操作没完成之前就进入到下一个循环.从而造成数据库连接数过多或数据库死锁等问题.
czg516 2006-01-10
  • 打赏
  • 举报
回复
不够分,我再另开帖子加,
如果我要描述的不清楚,
可以提出来.
Delphi TThread中文注释2009-10-22 16:58TThread是一个抽象类,可以创建几个独立的线程。 类关系 TObject 在一个多线程的应用程序中创建一个TThread的后子类代表一个线程。每一新子类的TThread对象的实例是一个新的线程。从TThread派生的多线程实例可以构成Delphi的多线程应用程序。    当一个应用程序运行时,应用程序就被载入内存准备执行。此时,它成为包含一个或多个线程的进程,每个线程含有数据、代码和系统资源。线程执行应用程序的部内容,并由系统配CPU时间。同一进程的所有线程共享同一地址空间,可以访问进程的全局变量。线程通过以下工作改善应用的性能:管理多通信设备的输入。    区任务的优先级。优先级高的处理紧急的任务。优先级低的处理其他任务。    以下是使用线程的一些建议:    同时跟踪太多的线程消耗CPU时间。对单处理器系统,一个进程最多有16个线程。    当多个线程更新相同的资源时,应使线程同步以避免冲突。    大多数访问VCL对象和更新窗体的方法必须从主VCL线程内部调用。    以下为创建和使用一个新线程的过程:    (1)单击File|New|Thread菜单项,创建一个包含对象的新单元,该对象源于TThread类。    (2)定义新线程对象和Create方法。    (3)通过插入线程执行时需要的代码定义线程对象和Execute方法。    (4)将使用VCL组件的任何调用传递给Synchronize方法,以避免多线程冲突。

4,012

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧