I am trying to understand the behavior of the engine in this instance:
Process 1 obtains a SHARED lock on a database.  Process 2 then steps an
INSERT statement and gets SQLITE_BUSY as expected.  However, Process 2 then
steps a different INSERT statement on the same connection, and it returns
SQLITE_DONE, with 1 change reported.  This is despite the active SHARED
lock.  Fortunately, this change never actually shows up in the database.

The key is, this only happens when I do not reset the first INSERT
immediately after the BUSY notification.  If I reset it, the second INSERT
correctly returns BUSY as well.

Now, I have determined it is good practice to do a reset in this case for
other reasons, and it is no problem.   However, what I would like explained
if possible is why a reset on statement 1 affects the locking behavior of
statement 2.  To my understanding a reset is only required when you
wish to reuse a statement or to ensure locks are dropped.  But in this
case the behavior is simply odd.

My only guess is that the library is in an internally inconsistent state,
and this is actually a "misuse of interface" which is not heuristically
detected by the engine, and so all bets are off.

I have a short piece of code which reproduces the problem on this OS X
system on 3.6.13 and on 3.1.3 (changing prepare_v2 to prepare).
Instructions are in the C code comments.  In short, initialize the DB with
the .sql file; obtain a shared lock on the database with the sqlite3 shell;
then run the C code.  The second insert should "succeed".

http://3e8.org/pub/write-misuse-demo.sql
http://3e8.org/pub/write-misuse-demo.c

Jim

-- 
[email protected] / 0x43340710 / 517B C658 D2CB 260D 3E1F  5ED1 6DB3 FBB9 4334 0710
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to