Fix para que Rails 2.3.8 y la concurrencia con Sqlite3

Sqlite is powerful, fast and small. It’s so nice working with it! There’s only one problem: concurrency.

A few weeks ago, we started receiving these errors in one application: SQLite3::BusyException: database is locked

And we are not the only ones: http://stackoverflow.com/questions/78801/sqlite3busyexception. After some testing we found out that the “timeout” option in database.yml was being ignored. When Rails has to write several things at the same time to the DB, it should wait for a few seconds before failing. In our tests, Rails just crashed whenever two write peticions arrived at the same time :(.

After some more investigation we found a possibly related bug in Rails dev: http://dev.rubyonrails.org/ticket/8811. And after some more investigation we found the solution (tested with Rails 2.3.8):

Edit this ActiveRecord file: activerecord-2.3.8/lib/active_record/connection_adapters/sqlite_adapter.rb

Replace this:

      def begin_db_transaction #:nodoc:
        catch_schema_changes { @connection.transaction }
      end

with

      def begin_db_transaction #:nodoc:
        catch_schema_changes { @connection.transaction(:immediate) }
      end

And that’s all! We haven’t noticed a performance drop and now the app supports many more petitions without breaking. Sqlite is nice!

Post a comment.