On 9-nov-2010, at 18:22 Peter Pawlowski wrote:

> While debugging an issue with using SQLite with a Rails  
> application, we
> discovered that the behavior of SQLite when setting the
> 'sqlite3_busy_timeout' option was unexpected.
>
> After reading and grokking the SQLite documentation about locking (or
> doing our best to, at least!) it seems that this is the expected
> behavior, but we'd like to confirm.
>
> Basically, we were surprised that in a specific case, an INSERT
> statement will fail immediately and not busy wait, even though a busy
> handler has been set.
>
> For example, given two sqlite3 shell processes, A and B:
>
>    A1. begin immediate;
>     # => locks the db
>    B1. .timeout 5000
>    B1. select * from foo;
>     # => succeeds
>    B2. insert into foo values ("bar");
>     # => hangs for 5 seconds, then fails with SQLITE_BUSY
>    B3. begin deferred transaction;
>    B4. insert into foo values ("bar");
>     # => hangs for 5 seconds, then fails with SQLITE_BUSY
>    B5. rollback;
>    B6. begin deferred transaction;
>    B7. select * from foo;
>     # => succeeds
>    B8. insert into foo values ("bar");
>     # => fails immediately with SQLITE_RUBY
>    B9. rollback;
>
> The surprising behavior is that step B8 fails immediately and does not
> retry for 5 seconds, which is what we were expecting since the
> busy_timeout is set in this case.
>
> Can someone confirm that this is the intended behavior?
>
> If so, we'd suggest some more documentation about how SQLite behaves
> when a busy handler is set. Of course we'd be happy to help by
> contributing content for the documentation.
>
> If you're interested: The specific consequence of this behavior is  
> that
> our Rails application with multiple processes fails with SQLITE_BUSY
> whenever concurrent write requests are made to the database. The Rails
> code allows setting busy_timeout, however it doesn't end up having any
> real effect because all SQLite interactions made by ActiveRecord (the
> Rails database abstraction) end up being complex transactions of type
> 'deferred' (the type is set in the sqlite3-ruby gem). This is probably
> one reason why the Rails folks seem to have the opinion that SQLite is
> not suitable for production systems.
>
> Once I confirm that this is the expected behavior of SQLite, we will
> attempt to address this issue with the sqlite3-ruby or Rails folks,
> since this would clearly need to be addressed at the application  
> level.
>
> thanks for your help!
>
> Peter

The immediate busy-error is indeed intended behaviour, or rather a  
consequence of the technical design.

It took me a while to find where it is documented. That is not in  
"Locking and Concurrency in SQLite version 3" but in the "C/C++ API  
Reference". And there it is not in the description of  
sqlite3_busy_timeout but under sqlite3_busy_handler. There it is  
explained clear enough.

What has surprised me that this deadlock is unchanged when accessing  
a database in WAL mode. Also then it is intended behaviour, this was  
explained in an earlier discussion. But I don't know if it will  
remain like this in future versions.

Best Regards, Edzard.

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to