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
-~----------~----~----~----~------~----~------~--~---

Reply via email to