Sorry Ralf, The real thing is far too big but here are two small test projects I made with the same code snippets that show the same behaviour. (sorry if the layout is poor, the code indentation seems to get lost when I post here) Project LongLock sets a lock for a time entered by the user by performing lots of updates inside a transaction. The other project, TimeoutWrite, sets a timeout entered by the user and then tries to write a single record to the same table. I then ran them both simultaneouly. If the timeout period in project TimeoutWrite is more than the lock period in project LongLock the 'New comment saved' message is displayed and the record is saved. If the timeout period in TimeoutWrite is less than the lock period in LongLock the 'New comment saved' message is still displayed (at the end of the timeout period) but the record is not saved. I was testing with a busy timeout of 3000ms in project TimeoutWrite and a lock time in project LongLock of between 1 and 10 seconds (by entering between 10 and 100 in the edit box) Howard This is Project LongLock that sets the lock (one form and a datamodule) ========================================= The Main form *********** unit MainFrmLongLock; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; Label1: TLabel; Label2: TLabel; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses U_DataModLongLock; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var i : integer; begin Label2.Caption := ('Database locked');application.ProcessMessages ; DataModLongLock.DISQLite3Database1.open; DataModLongLock.DISQLite3Database1.Execute('begin transaction;'); for i := 1 to strToInt(edit1.Text) do begin DataModLongLock.DISQLite3Database1.Execute('UPDATE Comments SET CommentDeptID = 8 WHERE CommentDeptID = 8;'); sleep(100); end; DataModLongLock.DISQLite3Database1.Execute('commit;'); DataModLongLock.DISQLite3Database1.close; Label2.Caption:=('Database free'); end; end. The Data Module *********** unit U_DataModLongLock; interface uses SysUtils, Classes, DISQLite3Database; type TDataModLongLock = class(TDataModule) DISQLite3Database1: TDISQLite3Database; private { Private declarations } public { Public declarations } end; var DataModLongLock: TDataModLongLock; implementation {$R *.dfm} end. ........................................................................................................... This is Project TimeoutWrite that tries to do the write (one form and a datamodule) ========================================= The Main form *********** unit U_MainTimeoutWrite; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TFrmTimeoutWrite = class(TForm) Edit1: TEdit; BtnWriteRecord: TButton; BtnSetTimeoutPeriod: TButton; procedure BtnWriteRecordClick(Sender: TObject); procedure BtnSetTimeoutPeriodClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var FrmTimeoutWrite: TFrmTimeoutWrite; implementation uses U_DataModTimeoutWrite, DISQLite3API; {$R *.dfm} procedure TFrmTimeoutWrite.BtnSetTimeoutPeriodClick(Sender: TObject); begin DataModTimeoutWrite.TimeoutValue := StrToInt(edit1.Text); //store timeout in data module end; procedure TFrmTimeoutWrite.BtnWriteRecordClick(Sender: TObject); var SQLiteReturnValue : integer; sql : string; begin sql :='insert into Comments (CommentText,CommentDeptID ) values (''Dummy text'', 8);' ; SQLiteReturnValue := DataModTimeoutWrite.ExecuteSQLWithLockedDBTimeOut(sql); //try to write record if SQLiteReturnValue = SQLITE_OK then //SQLITE_OK defined in DISQLite3API showmessage('New comment saved') else case SQLiteReturnValue of SQLITE_BUSY : showmessage ('Database is busy') ; SQLITE_LOCKED : Showmessage ('Database is locked'); Else showmessage ('Could not save. Error code: '+ inttostr(SQLiteReturnValue)); end;//case end; end. The Data Module *********** unit U_DataModTimeoutWrite; interface uses SysUtils, Classes, DISQLite3Database; type TDataModTimeoutWrite = class(TDataModule) DISQLite3Database1: TDISQLite3Database; private { Private declarations } public { Public declarations } function ExecuteSQLWithLockedDBTimeOut(sql: string): integer; var TimeoutValue : integer; //I know its bad to do this but its just a test program!! end; var DataModTimeoutWrite: TDataModTimeoutWrite; implementation uses strUtils, //for RightStr() DISQLite3API; //for sqlite3_busy_timeout {$R *.dfm} { TDataModTimeoutWrite } function TDataModTimeoutWrite.ExecuteSQLWithLockedDBTimeOut( sql: string): integer; var FullSQL : string; begin //Clean sql and make sure it ends with a semicolon sql := trim(sql); //remove spaces before and after if rightstr(sql,1) <> ';' then // no semicolon, need to add one sql := sql + ';'; FullSQL := 'Begin transaction; ' + sql + ' Commit;' ; try try DISQLite3Database1.Open; sqlite3_busy_timeout( DISQLite3Database1.Handle, TimeoutValue); //set busy timeout DISQLite3Database1.Execute(FullSQL); //try to run the sql until timeout Result := SQLITE_OK; // SQLITE_OK defined in DISqlite3API except on e: ESQLite3 do // If the DISQLite3 database engine raised this error, return the specific error code begin Result := e.ErrorCode; DISQLite3Database1.Rollback; //undo all the bits we were able to do end; else //for any other error simply re- raise it so it gets handled elsewhere raise end //try - except finally DISQLite3Database1.Close; end; //try - finally end; //Function end. ........................................................................................................... The test database contains just one table with the same structure as the one in my real application. The DLL to make the table is CREATE TABLE `Comments` ( SEFRowID INTEGER, CommentDateTime TEXT, CommentAuthor TEXT, CommentDeptID INTEGER, CommentText TEXT, CommentGrade INTEGER, KeyCriteriaPhrases Text, PRIMARY KEY(SEFRowID,CommentDateTime) ); CREATE INDEX indxSefRowID ON Comments (SEFRowID);