How to install busy_handler for SQLite3

I get too often SQLite3::BusyException and after searching a bit I
think I’d need to install a busy_hanlder to return true. That seems
to be per connection, how would you do this in a global way in Rails?

– fxn

I did this using an abstract base class and it seemed to work for me.

There’s a SQLite driver call busy_timeout() which just retries any
busy lookup up to a certain time limit, for example busy_timeout(2000)
will retry up to 2 seconds.

In app/models, create retry_model.rb:
class RetryModel < ActiveRecord::Base
self.abstract_class = true
self.connection.raw_connection.busy_timeout(2000) if
self.connection.adapter_name == ‘SQLite’
end

Then in all your models, change them to derive from retry_model
instead of ActiveRecord::Base, eg, chage:

class MyModel < ActiveRecord::Base

to:

class MyModel < RetryModel

That should make your BusyExceptions go away

On Jul 24, 2006, at 19:09, Michael Meckler wrote:

I did this using an abstract base class and it seemed to work for me.

There’s a SQLite driver call busy_timeout() which just retries any
busy lookup up to a certain time limit, for example busy_timeout(2000)
will retry up to 2 seconds.

That’s great! That means it retries many times up to 2 seconds and
then dies? Is that better than writing a busy_handler that simply
return true?

Yes, according to the SQLite API, calling busy_timeout(2000) means
SQLite will wait up to 2000 ms for a lock to clear before throwing a
BusyException. By default, it throws the exception immediately.

A busy_handler that just returns true defeats the purpose of busy
locking. If there’s something keeping a lock on your database for more
than two seconds, you want it to return an exception, because
something is really wrong.