I am developing an Tcl app on Linux with SQLite (v3.3.5), and last night I
stressed tested it. Sure enough, one of process died with this error being
caught, "CATCH: database is locked".
In the book, SQLite (version 2.x of SQLite) by Chris Newman, he writes on
page 184 that a way to test a Tcl callback function for a locked database is to
issue a BEGIN TRANSACTION in one session and run the program in another
session.
I just wanted to see the locked database error so I opened two windows and
started the sqlite command line program in each window. In one window I issued
the BEGIN TRANSACTION command. In the other I issued an INSERT command. The
INSERT command worked with no error. I then did the INSERT command in the
window with the BEGIN TRANSACTION and the database gave an error saying the
column name was not unique, so that means the INSERT worked fine in the other
window even though the database was supposed to be locked.
This is the Tcl code for accessing the database. It is supposed to try 5
times if a database is locked, but apparently crashes if the database is locked.
The Log message in QueryDataBase is there with the DB and QUERY info, but the
Log message in RunQuery for the ERROR return code is not there, so the proc
crashed before it.
Any suggestions or help is appreciated.
<pre>
proc QueryDataBase {resultDir dataBase query} {
set P [format "$::FW" "([lindex [info level 0] 0])"]
#
#
Log $resultDir "$P DB: $dataBase\n$P QUERY: $query"
set queryResult ""
for {set i 0} {$i < 5} {incr i} {
set queryResult [RunQuery $resultDir $dataBase $query]
if {$queryResult == "TCR_FAIL"} {Log $resultDir "$P QUERY FAILED";
after 250; continue}
break
}
if {$queryResult == "TCR_FAIL"} {set queryResult ""}
return $queryResult
} ;# QueryDataBase
#-------------------------------------------------------------------------------------------------
proc RunQuery {resultDir dataBase query} {
set P [format "$::FW" "([lindex [info level 0] 0])"]
#
#
sqlite dbCmd $dataBase
dbCmd timeout 300
set qryResult [dbCmd eval $query]
set errorCode [dbCmd errorcode]
dbCmd close
Log $resultDir "$P ERROR: $errorCode"
if {$errorCode} {set qryResult TCR_FAIL} ;# error code 0 = success
return $qryResult
} ;# RunQuery
</pre>