@linux-aarhus
Thanks. I’m not a developer; just a hack working on a project. Fortunately, the application itself has never had a lock issue, it is only when I’m updating the database while the application is open (which I ought not to do) and forget to commit the transaction before returning to the open application to see that the database changes are reflected in it. It’s likely my busy handler because I haven’t done much with it yet since I have to make up a scenario to trigger it and have deferred that for a bit.
Unless I can reproduce this using only two Konsole sessions— one running the SQLite CLI (removing my application altogether) and the other tclsh with SQLite loaded, I have no evidence to provide. I’m not suggesting there is some problem in the OS, Konsole, or SQLite; but was only wondering why the rolling back or committing doesn’t free the lock.
I’ll try to make an example that shows this occur but completely separate from my application and perhaps I can learn what I’m overlooking.Thanks.
@linux-aarhus
Here is an example that illustrates what I was trying to describe. I’m still not suggesting that the OS, Konsole, SQLite, or Tcl have anything wrong but would like to understand why the lock is not released under these circumstances which are, really, triggered by a user error or oversight.
First, I open a Konsole session/instance and run the SQLite CLI opening/creating a new database file. I think you have to write something to the database before SQLite creates the file.
❯ sqlite3 junk.db
SQLite version 3.53.4 2026-07-24 19:02:57
Enter ".help" for usage hints.
sqlite> create table t1 (key,value);
sqlite> insert into t1 values (1,'a');
sqlite> select * from t1;
╭─────┬───────╮
│ key │ value │
╞═════╪═══════╡
│ 1 │ a │
╰─────┴───────╯
Next, I open another Konsole session/instance and start a live Tcl session, connecting to the newly created database. Create a bad busy handler the never stops trying again to test for the release of a lock.
❯ tclsh
% package require sqlite3
3.53.4
% sqlite3 dbcmd junk.db
% dbcmd eval {select * from t1;}
1 a
% proc BusyHandler {attempts} {
chan puts stdout "Still waiting after $attempts attempts."
return 0
}
% dbcmd busy BusyHandler
Return to the SQlite CLI session in the first Konsole and open a transaction that acquires an immediate lock on the database.
sqlite> begin immediate;
Return to the Tcl live session in the the second Konsole and attempt to write to the database.
dbcmd eval {insert into t1 values (2,'b');}
The busy handler which fails to return a 1 after a maximum number of attempts keeps scrolling up the screen every time it tries again; and, then, Ctrl+Z to suspend the session.
Still waiting after 223675 attempts.
^Z
zsh: suspended tclsh
Return to the first Konsole and end the transaction, which should release the lock.
sqlite> rollback;
Return to the second Konsole and start a new Tcl live session connecting to the same database; and try to write to it.
❯ tclsh
% package require sqlite3
3.53.4
% sqlite3 dbcmd junk.db
% dbcmd eval {select * from t1;}
1 a
% dbcmd eval {insert into t1 values (2,'b');}
database is locked
%
Why does this instance of Konsole or Tcl live session still think that the database is locked? The old Tcl session was terminated, then the lock was released by the SQLite CLI that acquired it, and a new Tcl live session was started. Should the new Tcl session not know that the file is no longer locked? Or is the file still locked?
To test whether or not the file is still locked, I tried leaving that second Konsole session and opening a third with a new SQLite CLI session, and it failed.
❯ sqlite3 junk.db
SQLite version 3.53.4 2026-07-24 19:02:57
Enter ".help" for usage hints.
sqlite> select * from t1;
╭─────┬───────╮
│ key │ value │
╞═════╪═══════╡
│ 1 │ a │
╰─────┴───────╯
sqlite> insert into t1 values (2,'b');
Error near line 2: database is locked
But, if leave this third Konsole session just as it is and return to the second and exit the Tcl live session and exit Konsole, then return to third and repeat the write attempt, it succeeds.
sqlite> insert into t1 values (2,'b');
Error near line 2: database is locked
sqlite> insert into t1 values (2,'b');
sqlite> select * from t1;
╭─────┬───────╮
│ key │ value │
╞═════╪═══════╡
│ 1 │ a │
│ 2 │ b │
╰─────┴───────╯
This is what appears odd; for it was the first Konsole session running the SQLite CLI that acquired the lock and released the lock but it is the second session that appears to “keep the lock active” until Konsole is closed. I suppose it has something to do with using Ctrl+Z.
Anyway, sorry for the long explanation, but this was the crux of my original question and really has nothing to do with the specifics of my application code.
Of course, if I fix the BusyHandler to return 1 after some maximum number of attempts then it stops trying again and the Tcl live session does not have to be suspended and this does not occur.
Thanks.