多个进程同时访问Access数据库中的同一张表。只执行insert操作。
使用TADOQuery连接access,connectionString为:
'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
+ AMdbName + ';Persist Security Info=False;Mode=ReadWrite|Share Deny None';程序运行中发现偶尔会报:无法更新;当前被锁定 异常。请教高手:
1 access是否支持多进程同时插入?
2 如果支持,那我程序问题在那里?
谢谢!
使用TADOQuery连接access,connectionString为:
'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
+ AMdbName + ';Persist Security Info=False;Mode=ReadWrite|Share Deny None';程序运行中发现偶尔会报:无法更新;当前被锁定 异常。请教高手:
1 access是否支持多进程同时插入?
2 如果支持,那我程序问题在那里?
谢谢!
1,2,3楼朋友的意思是:Access本身不支持多个进程同时进行操作。必须我们自己管理进程间的同步,对么?
请指教,如何用sql语句来实现?
ADOQuery1.sql.clear;
ADOQuery1.SQL.Add('insert into jmdak (编号,姓名,所属社区) values (''9999'',''未输入'',''花园'')');
ADOQuery1.ExecSQL;
不同进程返回的句柄不相同。
按理说调用CreateMutex如果存在相同名称的互斥对象,则返回此对象的句柄。应该各进程返回的句柄相同。创建互斥对象代码:hmutex:=CreateMutex(nil,false,'mutex001');请高手指教,为啥返回句柄不同?
Qry : TADOQuery Qry.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
+ AMdbName + ';Persist Security Info=False;Mode=ReadWrite|Share Deny None';
with Qry do
begin
SQL.Clear;
SQL.Text := 'insert into rpt_info(fname,rpt) values(:fname,:rpt)';
Parameters.ParamByName('fname').Value := ARptName;
Parameters.ParamByName('rpt').LoadFromFile(ARpt, ftBlob);
EXECSQL;
end;
Qry.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
+ AMdbName + ';Persist Security Info=False;Mode=ReadWrite|Share Deny None';这个语句应该放在线程之外。
不知道你的多进程有没有数量限制?,如果有数量最好每个进程配备一个AOD,所有ADO共享一个连接ADOCONNECTION。这样最大可能预防进程之间的调用同一个AOD的冲突。
考虑进程间同步。但是使用进程间同步后,依然报无法更新错误。我就纳闷了。
下面是我写了个小列子程序:
程序循环向表中插入5000个随机数。
起2个程序同时插入。
MDB文件存于应用程序目录下,表名:testmp 只包含一个字段:Num(数字)
虽然使用Mutex同步,依然报无法更新错误。高手帮忙看看啥问题?unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB;type
TForm1 = class(TForm)
Memo1: TMemo;
Button2: TButton;
ADOQuery1: TADOQuery;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
HMutex:THandle;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button2Click(Sender: TObject);
var
I: Integer;
begin for I := 0 to 4999 do
begin
if WaitForSingleObject(HMutex,INFINITE) = WAIT_OBJECT_0 then
begin
try
with ADOQuery1 do
begin
SQL.Clear;
SQL.Add('Insert into testmp(Num) values(:Num)');
Randomize;
Parameters.ParamByName('Num').Value:=Random(1000);
Application.ProcessMessages;
ExecSQL;
Memo1.Lines.Add(IntToStr(i));
end;
except
on e:exception do
Memo1.Lines.Add(e.Message)
end;
end;
ReleaseMutex(HMutex);
end;
ADOQuery1.Close;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
HMutex:=CreateMutex(nil,false,'Mutex007');
ADOQuery1.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
+ ExtractFilePath(ParamStr(0))+'test.mdb' + ';Persist Security Info=False;Mode=ReadWrite|Share Deny None';
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
CloseHandle(HMutex);
end;
end.
这样的话,同步没问题了。procedure TForm1.Button2Click(Sender: TObject);
var
I: Integer;
begin
Memo1.Lines.Clear;
for I := 0 to 49999 do
begin
if WaitForSingleObject(HMutex,INFINITE) = WAIT_OBJECT_0 then
begin
try
ADOConnection1.Open;
with ADOQuery1 do
begin
SQL.Clear;
SQL.Add('Insert into testmp(Num) values(:Num)');
Randomize;
Parameters.ParamByName('Num').Value:=Random(1000);
Application.ProcessMessages;
ExecSQL;
Memo1.Lines.Add(IntToStr(i));
end;
ADOConnection1.Close;
except
on e:exception do
begin
Label1.Caption:=e.Message;
Memo1.Lines.Add(e.Message);
end;
end;
end;
ReleaseMutex(HMutex);
end;
end;
var
I: Integer;
begin
Memo1.Lines.Clear;
ADOConnection1.Open;//这个放在循环外边 for I := 0 to 49999 do
begin
if WaitForSingleObject(HMutex,INFINITE) = WAIT_OBJECT_0 then
begin
try
with ADOQuery1 do
begin
SQL.Clear;
SQL.Add('Insert into testmp(Num) values(:Num)');
Randomize;
Parameters.ParamByName('Num').Value:=Random(1000);
Application.ProcessMessages;
ExecSQL;
sleep(30);//给系统一点时间来处理数据,这个时间可调整,具体到多少,我也不确定。数据量越大,数据库处理数据越慢,这个数应该越大。1秒为1000.
Memo1.Lines.Add(IntToStr(i));
end;
except
on e:exception do
begin
Label1.Caption:=e.Message;
Memo1.Lines.Add(e.Message);
end;
end;
end;
ReleaseMutex(HMutex);
end;
ADOConnection1.Close;//放在循环外边end;
EnterCriticalSection(cs);
{插入数据到ACESS}
LeaveCriticalSection(cs);
CSDN都没几个能分清进程跟线程的不同吗? LZ问的是进程啊.
如果是线程随便都处理好了还用问!?