下面一个简单的示例,会造成死锁,大家可以试一下,到底是什么原因呢?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造成的。
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造成的。
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货