急救? 用ado连acess2000 为什么会出现表被锁定的情况 写入数据还很慢?(再次提问)(100分)

  • 主题发起人 主题发起人 longshine
  • 开始时间 开始时间
L

longshine

Unregistered / Unconfirmed
GUEST, unregistred user!
用ado连acess2000 为什么会出现表被锁定的情况 写入数据还很慢


下面我把我碰到的问题详细说明一下:
一个acess数据库中有多个表,而且这多个表是相互关联的
比如有三个表客户表 帐户表 合同表 客户表中的有一个字段为cust_id, 帐户表和合同表都
要用到cust_id, 而合同表又要用到帐户表中的account_id
因此这三个表写入有先后顺序 依次为客户表 帐户表 合同表

对于这三个表的处理 我使用了三个类来实现 每个类封装了ADOQUERY组件,(也就是说没有把
adoquery显式的放在窗体上,不知道这样又没有什么问题? )这样的话是不是adoquery的属性
都是默认的


//下面就是一个客户表处理的类
unit TCustomer;

interface
uses
ADODB;

type
TCustAcpt = class
private
ADOQuery: TADOQuery;

public
m_sCustId : string;
m_sStateId : string;
..............

function WriteCustomInfo() : integer;

constructor Create;//(AOwner: TComponent); override;
destructor Destroy; override;

end;
implementation

{ TCustAcpt }


constructor TCustAcpt.Create;
begin
inherited Create;//(AOwner);
ADOQuery := TADOQuery.Create(nil);
ADOQuery.ConnectionString := sConnectionString;
end;

destructor TCustAcpt.Destroy;
begin
ADOQuery.Free;
inherited Destroy;
end;


function TCustAcpt.WriteCustomInfo: integer;
var
m_sSQL : string;
m_sTableName : string;

begin

m_sTableName := 't_customer';
m_sSQL := 'insert into ' + m_sTableName +
'(cust_id, state_id, acpt_route_id, cus_type_id, ......) values ' +
'(:cust_id, :state_id, :acpt_route_id, :cus_type_id, .......)';
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add(m_sSQL);
ADOQuery.Parameters.ParamByName('cust_id').Value := m_sCustId ;
ADOQuery.Parameters.ParamByName('state_id').Value := m_sStateId ;
ADOQuery.Parameters.ParamByName('acpt_route_id').Value := m_sAcptRouteId ;
ADOQuery.Parameters.ParamByName('cus_type_id').Value := m_sCusTypeId ;
.............
ADOQuery.ExecSQL;

ADOQuery.Close;

end;

end.




同样定义了两个帐户和合同表处理的类 TAcntAcpt TCntrctAcpt


当我循环向数据库中写记录的时候 如果不延时就会出现表锁定的情况
tCust : array of TCustAcpt;
tAcnt : array of TAcntAcpt;
tCntrct : array of TCntrctAcpt;

for i:=0 to n do
begin
tCust = TCustAcpt.create;
tAcnt = TAcntAcpt.create;
tCntrct = TCntrctAcpt.create;
tCust.WriteCustomInfo;//写入客户信息
tAcnt.WriteAccountInfo;//写入帐户信息
tCntrct.WriteCntrctInfo;//写入合同信息
sleep(500); //如果不加这句话表就会被锁定 出现 无法读取记录;正被另一用户锁定
//我很奇怪 我只是向表中写入数据 又没读数据 为什么会说无法读记录呢?
//为什么会被锁定呢?
tCust.free;
tAcnt.free;
tCntrct.free;
end;



这个程序实现起来 会出现表被锁定的情况 写入数据也很慢 这是为什么?
 
:longshine:
写入数据慢的问题可能是你封装的query连接的次数太多(在你的循环中有3*n次链接),解决的办法可以在各个类中加入connection属性,让query直接链到一个常链数据库的connection。

关于锁定,就用同一个类,不要定义:
tCust : array of TCustAcpt;
tAcnt : array of TAcntAcpt;
tCntrct : array of TCntrctAcpt;
应该为:
tCust : TCustAcpt;
tAcnt : TAcntAcpt;
tCntrct : TCntrctAcpt;

tCust = TCustAcpt.create;
tAcnt = TAcntAcpt.create;
tCntrct = TCntrctAcpt.create;
... 初始化

for i:=0 to n do
begin
tCust.WriteCustomInfo;//写入客户信息
tAcnt.WriteAccountInfo;//写入帐户信息
tCntrct.WriteCntrctInfo;//写入合同信息
// sleep(500); no use //如果不加这句话表就会被锁定 出现 无法读取记录;正被另一用户锁定
//我很奇怪 我只是向表中写入数据 又没读数据 为什么会说无法读记录呢?
//为什么会被锁定呢?
end;
tCust.free;
tAcnt.free;
tCntrct.free;

不同对象操作同意个表,有可能产生锁定,同一对象就不会有此问题。
try it
 
我想问一下
:解决的办法可以在各个类中加入connection属性,让query直接链到一个常链数据库的connection。
那应该怎么实现呢? 请赐教
 
在数据模块中加一个连接,所有QUERY都用这个连接连接数据库
你只有一个数据库就只用一个连接行了,
这样类的封装不能保证,但性能可以提高许多
 
procedure SetConnection(const Value: TADOConnection);
function GetConnection: TADOConnection;
....
property Connection: TADOConnection read GetConnection write SetConnection;

procedure TCustAcpt.SetConnection(const Value: TADOConnection);
begin
ADOQuery.Connection := Value;
end;

function TCustAcpt.GetConnection: TADOConnection;
begin
Result := ADOQuery.Connection;
end;
 
ADOQuery := TADOQuery.Create(nil);
ADOQuery.ConnectionString := sConnectionString;
这样建立多个连接当然会发生记录锁定了,还不如换数据库,SQL Server2000个人版
.控制起来容易多了。
 
多人接受答案了。
 
后退
顶部