下面一個簡單的示例,會造成死鎖,大家可以試一下,到底是什么原因呢?
db:TDatabase;
qry,qryTemp:TQuery;
procedure ExecuteSQL(strSQL:string);
begin
qryTemp.SQL.Text:=strSQL;
qryTemp.ExecSQL;
end;
procedure ButtonClick(Sender:TObject);
begin
db.StartTransaction;
ExecuteSQL('Insert Into Table1(Name)Values(''a'')');
qry.SQL.Text:='Select * From Table1(NoLock) Where Name=''a''';
qry.Active:=True;
ExecuteSQL('Insert Into Table2(Name)Values(''b'')');
qry.Next; //如果去掉這句,則不會死鎖
ExecuteSQL('Update Table2 Set Name=''c'' Where Name=''b'''); //如果加上qry.Next,在這里會死鎖
db.Rollback;
end;
1、不要糾結這段代碼做這么無聊的事,只是用來測驗死鎖;
2、Table1及Table2表結構為:
ID numeric 主鍵標識
Name varchar(50)
3、為什么加上qry.Next就會死鎖,不加上就沒事?我用Delphi6+SQL Server2000及Delphi XE+SQL Server2008都測驗過,同樣存在這個問題,應該不是Delphi的Bug造成的。
uj5u.com熱心網友回復:
測驗了一下,用ADO沒事,看來是BDE的問題造成的了。uj5u.com熱心網友回復:
你這段代碼是多個實體同時執行的嗎?單個事務不可能導致死鎖。如果是多個同時執行,那么看看的你BDE的鎖定級別或事務隔離級別之類的相關的引數項,看看是不是使用悲觀鎖。uj5u.com熱心網友回復:
建議你使用ADO的
uj5u.com熱心網友回復:
同意樓上~ ADO轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/120018.html
標籤:數據庫相關
