Tofig Hasanov
Tofig Hasanov

Reputation: 3709

Rails ActiveRecord connection session

I have the following piece of code in Rails 3.2 + mySQL application:

ActiveRecord::Base.connection.execute("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED")
ActiveRecord::Base.transaction do
              @book = ActiveRecord::Base.connection.execute("select * from books limit 1")
end

As far as I understand the first statement will result in the next ONE transaction within same session to be in "READ UNCOMMITTED" isolation and then isolation will return to default.

My questions are: Can I be sure that the transaction block will always be executed in the same session? Also, can I be sure that no other transaction will take place in the same session between the first and the second statement?

I tried to Google for this topic, but as I am new to Rails I couldn't find any explanation that would make this clear to me. Any help would be appreciated!

Thank you!

Upvotes: 0

Views: 1205

Answers (1)

Matouš Borák
Matouš Borák

Reputation: 15954

I think that all your questions can be answered with a "YES". Even in Rails 3.2, the connections to the database are managed by the connection pool. This pool ensures that each thread will have its own dedicated connection to the DB. The pool assigns connections to threads based on their Thread IDs which are unique for each thread. Read the docs for more info.

So I think it should not be possible for two threads to share a connection and thus a MySQL session at the same time. Also, it should be guaranteed that the transaction will always be called using the same connection (i.e. in the same session) as the isolation level setting code.

By the way, if you used Rails 4 or higher, you could achieve the same behavior using the transaction method only. Unfortunately, setting isolation levels is not supported this way in Rails 3. So the following example actually won't work in your particular scenario:

Book.transaction(:isolation => :read_uncommitted) do
  @book = Book.first
end
# => SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
#    BEGIN
#      SELECT  `books`.* FROM `books`  ORDER BY `books`.`id` ASC LIMIT 1
#    COMMIT

Upvotes: 4

Related Questions