Richard Klein wrote:

Requiring the second transaction to complete first is expected in
terms of SQLIte's concurrency system.

So in terms of using SQLite, I need to close the entire transaction and restart it when I get a "database locked" return code in a writer thread? It's not enough to just retry the commit in a little while?

You don't need to close the connection, but you do need to ROLLBACK
the transaction, unless you have some sort of a priori knowledge that
the second transaction will not try to write to the database.  In such
a case, the second transaction will not try to acquire the RESERVED lock
already held by the first transaction, and so the second transaction
will eventually run to completion.  In such a scenario, the first
transaction can sit in a busy wait loop (sleep for a bit, then retry
the COMMIT) until the COMMIT succeeds.

However, if the second transaction will (or might) try to write to the
database, you must ROLLBACK the first transaction, sleep for a bit, and
restart the first transaction.

I've written the attached test program.

In this program, I run 2 threads, each opening an explicit transaction (begin immediate), inserting a row into a table, and committing the transaction. I run the program 4 times, in loopback mounted directories, using JFS, Ext3, TMPFS and ReiserFS3.

I expected that it would be possible for the program to get SQLITE_BUSY only for the begin statement, however, based on the underlying filesystem, I get:

Ext3: takes 6 seconds to run on my system, with SQLITE_BUSY happening for commit even though each thread has a RESERVED lock on the database.

JFS: takes 4 seconds to run on my system, with SQLITE_BUSY happening for commit.

ReiserFS version 3: takes 90 (!!!) seconds on my system, with SQLITE_BUSY happening for commit, and the threads nearly completely serialized.

Tmpfs: Takes 2 seconds, again with SQLITE_BUSY happening for the commit statements.

My questions are:
1. Why do I get SQLITE_BUSY for commit statements? Each thread has a reserved lock - there should be no busy situation for anything other than a "begin immediate" operation.
2. Why does running on reiserfs cause such a huge performance penalty?
3. Another weird thing - if I change the program to open a deferred transaction, instead of an immediate transaction, the program doesn't deadlock, even when I get a SQLITE_BUSY on an insert statement.

Thanks
Lior
- Richard Klein


------------------------------------------------------------------------

-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Attachment: test.c.gz
Description: GNU Zip compressed data

-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to