ActiveRecord 3.0, 3.2 thread safety and connection pool fairness

I’ve been trying to run a few non-Rails ActiveRecord apps in a Java
servlet
container in full multithreaded mode. I kept running into problems
under
moderate load, and I believe I’ve tracked down the causes.

I want to post this for posterity and ask if other JRuby users have
seen these
same problems. I am also seeking testing and comments on my patches, if
possible.

  1. ActiveRecord has thread safety issues. I see this error in my logs
    “Detected invalid hash contents due to unsynchronized modifications
    with
    concurrent users org/jruby/RubyHash.java:1356:in `keys’”

Fix accepted: Synchronize read and modification of @reserved_connections by pmahoney · Pull Request #6398 · rails/rails · GitHub

  1. ActiveRecord’s connection pool is not “fair”. My thread pool is
    larger
    than my database connection pool, and I regularly see timeouts
    acquiring
    database connections under only moderate load (where direct JDBC calls
    for
    a container-managed connection pool see no such timeouts).

Fix also accepted (though it somehow breaks tests of eager loading on
postgres),
but this is more complex and not so clean:

I’m a bit surprised/nervous if I am the first to encounter these
issues…

Thanks,


Patrick M.

On 2012-05-22, at 18:49, Patrick M. wrote:

  1. ActiveRecord’s connection pool is not “fair”. My thread pool is larger
    than my database connection pool, and I regularly see timeouts acquiring
    database connections under only moderate load (where direct JDBC calls for
    a container-managed connection pool see no such timeouts).

Last I looked at the AR DB connection pool, it never released
connections for active threads. That means you MUST have at least as
many connections in your pool as you have active threads. In a web app,
the threads are often short lived, and the connections they occupy are
released when the thread dies. This is not the case for long-lived
threads in a non-web app.


Uwe K.

I had to manually remove the connections in a multithreaded Swing app.

ActiveRecord::Base.clear_active_connections!

Regards
Roger

Am 23.05.2012 um 15:55 schrieb Uwe K.: