Patrick Beckers
2006-11-10 15:02:49 UTC
I'm struggling with a problem for some time now, and I don't know how to
solve it. Perhaps you experts can help me out.
I have a function (listed below) which generates a new number, depending on
the type of document (Doc).
We use Interbase 7.5 as the database-server and mixed clients: Delphi7/Win32
(local and via Citrix) and Delphi7/Intraweb (local and via Internet)
The problem is that in a multi-user environement with 50 users or so, this
functions sometimes generates a "Lock conflict on no wait transaction
deadlock." on the client machine. Not always, but enough the become really
annoying.
We used this function for several years, and it always ran smoothly (on
Interbase 4, 6, 7, 7.5 and Delphi 3, 5, 7).
I'm not sure it started right after we upgraded to Interbase 7 or 7.5,
because users don't always report such errors (except when it occurs several
times a day).
Basically, DOCUMENTNR is a small table containing only 13 records. Here's
the layout:
-------------------
SHOW TABLE documentnr
DOC SMALLINT Nullable
NUMBER INTEGER Nullable
-------------------
SHOW INDEX documentnr
DOCUMENTNR_DOC INDEX ON DOCUMENTNR(DOC)
-------------------
In IBconfig75, I've tried changing some parameters - without succes.
These are the current settings:
CPU_AFFINITY 3
ENABLE_HYPERTHREADING 1
MAX_THREADS 10000
V4_LOCK_MEM_SIZE 524250
DATABASE_CACHE_PAGES 20000
Over time, I've tried changing values for some of these parameters. Also,
default settings don't solve it.
Btw, the database pagesize is 8192
All Win32 clients connect with the IB server through a single IBDatabase1
and IBTransaction1, located on the datamodule DM.
The params of IBTransaction1 are read_committed, rec_version, nowait
This is the function. It reads the current number according to Doc (type of
document) from the table and increments it with 1. Then, it updates the
table with the new number.
function NewDocumentNumber(Doc:Integer):Integer;
var Q : TIBQuery;
Num : integer;
begin
Result := 0;
Q := TIBQuery.create( nil);
try
Q.Database := DM.IBDatabase1;
Q.Transaction := DM.IBTransaction1;
Q.UniDirectional := true;
Q.SQL.Clear;
Q.SQL.Add( 'select number from DOCUMENTNR where doc = '+IntToStr(Doc));
Q.Open;
if not Q.EOF then
Num := Q.FieldByName('number').AsInteger + 1
else
Num := 1;
Q.close;
Q.SQL.Clear;
Q.SQL.Add( 'update DOCUMENTNR set number = '+IntToStr(Num)+
' where doc = '+IntToStr(Doc));
Q.ExecSQL;
Q.close;
Result := Num;
finally
Q.Free;
end;
end;
solve it. Perhaps you experts can help me out.
I have a function (listed below) which generates a new number, depending on
the type of document (Doc).
We use Interbase 7.5 as the database-server and mixed clients: Delphi7/Win32
(local and via Citrix) and Delphi7/Intraweb (local and via Internet)
The problem is that in a multi-user environement with 50 users or so, this
functions sometimes generates a "Lock conflict on no wait transaction
deadlock." on the client machine. Not always, but enough the become really
annoying.
We used this function for several years, and it always ran smoothly (on
Interbase 4, 6, 7, 7.5 and Delphi 3, 5, 7).
I'm not sure it started right after we upgraded to Interbase 7 or 7.5,
because users don't always report such errors (except when it occurs several
times a day).
Basically, DOCUMENTNR is a small table containing only 13 records. Here's
the layout:
-------------------
SHOW TABLE documentnr
DOC SMALLINT Nullable
NUMBER INTEGER Nullable
-------------------
SHOW INDEX documentnr
DOCUMENTNR_DOC INDEX ON DOCUMENTNR(DOC)
-------------------
In IBconfig75, I've tried changing some parameters - without succes.
These are the current settings:
CPU_AFFINITY 3
ENABLE_HYPERTHREADING 1
MAX_THREADS 10000
V4_LOCK_MEM_SIZE 524250
DATABASE_CACHE_PAGES 20000
Over time, I've tried changing values for some of these parameters. Also,
default settings don't solve it.
Btw, the database pagesize is 8192
All Win32 clients connect with the IB server through a single IBDatabase1
and IBTransaction1, located on the datamodule DM.
The params of IBTransaction1 are read_committed, rec_version, nowait
This is the function. It reads the current number according to Doc (type of
document) from the table and increments it with 1. Then, it updates the
table with the new number.
function NewDocumentNumber(Doc:Integer):Integer;
var Q : TIBQuery;
Num : integer;
begin
Result := 0;
Q := TIBQuery.create( nil);
try
Q.Database := DM.IBDatabase1;
Q.Transaction := DM.IBTransaction1;
Q.UniDirectional := true;
Q.SQL.Clear;
Q.SQL.Add( 'select number from DOCUMENTNR where doc = '+IntToStr(Doc));
Q.Open;
if not Q.EOF then
Num := Q.FieldByName('number').AsInteger + 1
else
Num := 1;
Q.close;
Q.SQL.Clear;
Q.SQL.Add( 'update DOCUMENTNR set number = '+IntToStr(Num)+
' where doc = '+IntToStr(Doc));
Q.ExecSQL;
Q.close;
Result := Num;
finally
Q.Free;
end;
end;