十万万火急!!!C++ Builder数据集以CachedUpdates方式(多人使用时)提交到SQL Server数据库为什么总是产生死锁(DeadLock)

  • 主题发起人 主题发起人 trybird
  • 开始时间 开始时间
T

trybird

Unregistered / Unconfirmed
GUEST, unregistred user!
十万万火急!!!C++ Builder数据集以CachedUpdates方式(多人使用时)提交到SQL Server数据库为什么总是产生死锁(DeadLock)?(200分)<br />C++ Builder 5.0 在 SQL Server 7.0环境下编程,数据集以CachedUpdates属性为true方式(多人使用时)
提交到SQL Server数据库,为什么总是产生死锁(DeadLock)?

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Fmain->Database1->StartTransaction();
//Database1的DatabaseName属性是SQL SERVER服务器中的一个数据库名;
Fmain->Database2->StartTransaction();
//Database2的DatabaseName属性是同一个SQL SERVER服务器中的另一个数据库名;
try
{
DataModule1->Table1->ApplyUpdates();//Error4
//DataMocule1是Database1的一个数据模块,
DataModule2->Table2->ApplyUpdates();/*Error3:EDBEngineError with message
'lock time out,SQLServer connection time out'*/
//DataMocule2是Database2的一个数据模块,Table1和Table2所指向的表结构相同,内容一致。
Fmain->Database1->Commit();
Fmain->Database2->Commit();
}
catch(Exception &amp;E)
{
Fmain->Database1->Rollback();
Fmain->Database2->Rollback();
throw;
}
DataModule2->Table2->CommitUpdates();
//Error1:BLOB not opened. Error2:Record already locked by this session.
DataModule1->Table1->CommitUpdates();

}
return;
}

出错提示:
Error1: BLOB not opened.
Error2:Record already locked by this session.
Error3:EDBEngineError with message 'lock time out,SQLServer connection time out'.
Error4:同Error3

在几个人同时用时,这段代码在会出现异常,大致规律是:
第一次:出现Error1错误。
第二次:出现Error2错误。
第三次:在SQL沙漏光标停留五六分钟后,出现Error3错误。
第三次以后:重复第三次的错误。
(有时又没有规律,直接出现Error3错误。而且在Error4处也会出现Error3的问题。)
重启SQL SERVER后正常,但不久有出现以上问题。
我的问题是:这段代码有什么不妥之处?如何缩短死锁异常的时间(五六分钟太长)?
 
肯定会出现死锁的,因为你用Ttable来访问远端数据库,在访问远端数据库时,千万不能用
Ttable,只能用Tquery+TupdateSQl,否则吃尽苦头。
 
fstao大虾:

谢谢!我们还想知道为什么“千万不能用Ttable,只能用Tquery+TupdateSQl”?
您知道我们主要要对远端数据库的表进行增、删、改,当然也查询,但多个人一用
就造成SQL Server死锁,只好重新启动SQL服务!

欢迎fstao大虾及众大虾继续不吝赐教!多谢!
 
另外我们程序中的Table之间有Master/Detail关系,代码中省略了从属明细表,
不知用“Tquery+TupdateSQl”能否及怎样实现Master/Detail关系!
 
因为Ttable和Tquery的机制不同的。用Tquery当然也能对进行增、删、改、查询,如果要
增、删、改就要用Tquery+Tupdatesql了。比如某个表:dbo.table1,
query1的Cachedupdate=true,Requestlive=false
在updatesql1的modifysql
update table1
set name=:name
where
id=:old_id

在insertsql:
insert into table1(id,name)
values (:id,:name)

在deletesql:
delete from table1 where id=:old_id

在master/detail也可以用tquery+tupdatesql,在detail表的query2的sql=select id1,id
,name where id=:id
query2的onnewrecord事件为:query2->fielbyname("id")->asinteger=query1->fieldbyname("id")->asinteger;
在master表的query1的AfterScroll事件:
query2->parambyname("id")->Asinteger=query1->fieldbyname("id")->Asinteger;
query2->Close();
Query2->Open();




 
接受答案了.
 
后退
顶部