一个加油站实时监控系统,加油站每加完一次油数据自动上传,
oracle8.05 远程数据库,采用ODBC连接,从CRecordSet继承来的类,
由于网络不好经常断线,所以写入数据经常丢失,而且程序也死掉了,
有时甚至出现数据库中数据表锁死现象,造成数据不能更新和插入,已经发生过,
怎样能在程序中判断连接的状态,同时又对程序的实时性没有影响?
请指教~~
oracle8.05 远程数据库,采用ODBC连接,从CRecordSet继承来的类,
由于网络不好经常断线,所以写入数据经常丢失,而且程序也死掉了,
有时甚至出现数据库中数据表锁死现象,造成数据不能更新和插入,已经发生过,
怎样能在程序中判断连接的状态,同时又对程序的实时性没有影响?
请指教~~
1、使用事务,即使断线了也能确保数据的一致性。
2、捕捉错误事件,判断连接是否已断开,如果是马上再连上。
3、设定一个最佳的timeout时间,使得程序不致于死机和处理事务的时间不能太长,又不能老是断线出错。
用try执行 catch捕捉所有错误,可是经常捕捉不到,加断点根本就没有执行完try就跳出了,
所以一旦断网,本以为事务处理能保证数据的一致性,我是暂时把不能提交远程数据库的数据
存到本地了,如果不能正常处理连接错误的话,还是会出现程序崩溃。重新连接数据库我不知道怎么实现,不过好像在超时限定内重新把拔掉的网线结上,一切正常。
判断连接是否断开?这正是我要问的问题,我不会啊:)超时设置也没有用过,只是知道可以设置,我用了CDatabase和CRecordSet继承来的数据集相关联
,超时不知道怎么设置。请多多关照:)
中断后你可以再重新建立一个新的连接。
一个事务尽可能的短,否则用户多了有可能会造成数据库中数据表锁死现象
因为我没有做过远程连接,这也仅仅是我的猜测,也不知对不对
就好像进入了死循环,代码如下
CDatabase *pdb=&(((CjyApp*)AfxGetApp())->db);
CMyData set;
int num=1000;
for(int i=1;i<999;i++)
{
pdb->begintrans();
try{
CString pzh,strFilter;
pzh.Format("%d",num+i);
strFilter.Format("pzh='%s'",pzh);
if(set.IsOpen())set.Close();
set.strFilter=strFilter;
set.Open();
if(set.GetRecordCount()>0)
{
set.Close();
pdb->CommitTrans();
continue;
}
set.AddNew();
set.m_RQ=CTime::GetCurrentTime();
……//具体13个数据,为float 和 CString型
set.UpData();
pdb->CommitTrans();
}
catch(CException *pe)
{
pe->ReportError();
pe->Delete();
pdb->Rollback();
}
if(set.IsOpen())
set.Close();
}
CDatabase *pdb=&(((CjyApp*)AfxGetApp())->db);
CMyData set;
int num=1000;
pdb->begintrans();
try{ for(int i=1;i<999;i++)
{
CString pzh,strFilter;
pzh.Format("%d",num+i);
strFilter.Format("pzh='%s'",pzh);
if(set.IsOpen())set.Close();
set.strFilter=strFilter;
set.Open();
if(set.GetRecordCount()>0)
{
set.Close();
pdb->CommitTrans();
continue;
}
set.AddNew();
set.m_RQ=CTime::GetCurrentTime();
……//具体13个数据,为float 和 CString型
set.UpData();
if(set.IsOpen())
set.Close();
}
}
catch(CException *pe)
{
pe->ReportError();
pe->Delete();
pdb->Rollback();
if(set.IsOpen())
set.Close();
return ;
}
if(set.IsOpen())
set.Close();
pdb->CommitTrans();
CDatabase *pdb=&(((CjyApp*)AfxGetApp())->db);
CMyData set;
int num=1000;
pdb->begintrans();
try{ for(int i=1;i<999;i++)
{
CString pzh,strFilter;
pzh.Format("%d",num+i);
strFilter.Format("pzh='%s'",pzh);
if(set.IsOpen())set.Close();
set.strFilter=strFilter;
set.Open();
if(set.GetRecordCount()>0)
{
set.Close();
continue;
}
set.AddNew();
set.m_RQ=CTime::GetCurrentTime();
……//具体13个数据,为float 和 CString型
set.UpData();
if(set.IsOpen())
set.Close();
}
}
catch(CException *pe)
{
pe->ReportError();
pe->Delete();
pdb->Rollback();
if(set.IsOpen())
set.Close();
return ;
}
if(set.IsOpen())
set.Close();
pdb->CommitTrans();
CString pzh,strFilter;
pzh.Format("%d",num+i);
strFilter.Format("pzh='%s'",pzh);
if(set.IsOpen())set.Close();
set.strFilter=strFilter;
set.Open();
if(set.GetRecordCount()>0)
{
set.Close();
pdb->CommitTrans();
continue;
}
先检查凭证号有没有重复,如果有重复set.GetRecordCount() 会返回 1 ,
如果有返回值关闭记录集,结束事务
之后又执行 CommitTrans();可能会出错的