sqlite3 can only handle one write at a time. It raises the locked exception
when another thread or process has an exclusive lock on the db. I got around
this by putting a wrapper around the lowest-level query methods which will
retry up to 4 times before passing the exception up the stack. Here's my code,
which I placed in the same file as my model definitions:
# Override database read and write methods so that they will retry 4 times
before raising an exception.
class DataObjects::Sqlite3::Command
alias original_execute_non_query execute_non_query
alias original_execute_reader execute_reader
def execute_non_query(*args)
try_again = 0
begin
original_execute_non_query(*args)
rescue Sqlite3Error => e
raise unless e.message =~ /locked/ || e.message =~ /busy/
if try_again < 5
try_again += 1
#VipLog.debug "locked or busy - retrying (#{try_again})"
retry
else
raise
end
end
end
def execute_reader(*args)
try_again = 0
begin
original_execute_reader(*args)
rescue Sqlite3Error => e
raise unless e.message =~ /locked/ || e.message =~ /busy/
if try_again < 5
try_again += 1
#VipLog.debug "locked or busy - retrying (#{try_again})"
retry
else
raise
end
end
end
end
Hope this helps!
Earle
Philipp Schmid wrote:
> Hi,
>
> I have an application that uses datamapper where it can happen that a
> few (1-30) threads write to database concurrently.
>
> I get the following error quite often: Sqlite3Error: database is
> locked
>
> I'm I getting "thread safety" wrong here or is this a datamapper bug?
>
> Lg Philipp
>
> ps: I use a debian lenny sqlite version (3.5.9) backported to debian
> etch.
>
>
> #<Sqlite3Error: database is locked>
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/
> data_objects_adapter.rb:92:in `execute_non_query'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/
> data_objects_adapter.rb:92:in `execute'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/
> data_objects_adapter.rb:171:in `with_connection'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/
> data_objects_adapter.rb:90:in `execute'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/
> data_objects_adapter.rb:26:in `create'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/
> data_objects_adapter.rb:15:in `each'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/adapters/
> data_objects_adapter.rb:15:in `create'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/repository.rb:
> 51:in `create'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/resource.rb:
> 555:in `hookable__create_nan_before_advised'
> /usr/lib/ruby/gems/1.8/gems/extlib-0.9.8/lib/extlib/hook.rb:294:in
> `create'
> /usr/lib/ruby/gems/1.8/gems/extlib-0.9.8/lib/extlib/hook.rb:292:in
> `catch'
> /usr/lib/ruby/gems/1.8/gems/extlib-0.9.8/lib/extlib/hook.rb:292:in
> `create'
> /usr/lib/ruby/gems/1.8/gems/dm-core-0.9.6/lib/dm-core/resource.rb:
> 280:in `hookable__save_nan_before_advised'
> /usr/lib/ruby/gems/1.8/gems/extlib-0.9.8/lib/extlib/hook.rb:294:in
> `save'
> /usr/lib/ruby/gems/1.8/gems/extlib-0.9.8/lib/extlib/hook.rb:292:in
> `catch'
> /usr/lib/ruby/gems/1.8/gems/extlib-0.9.8/lib/extlib/hook.rb:292:in
> `save'
>
>
> >
>
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"DataMapper" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/datamapper?hl=en
-~----------~----~----~----~------~----~------~--~---