Skip to content

Query order processed by arproxy is different from the order actually executed if lazy_transactions is enabled #23

@shallow1729

Description

@shallow1729

From Rails 6, ActiveRecord::Base.transaction does not execute BEGIN; and it is executed at the first query of the transaction instead.
rails/rails#32647
it seems that this change cause the process order gap between arproxy and actually executed transaction.

Here is an example.

ActiveRecord::Base.transaction do
  User.find(1)
end

This case seems to be processed as follows

1. initialize transaction but doesn’t execute `BEGIN`
2. call `execute(sql, name)` of `User.find(1)`, the query of which is like "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1" 
3. before executing the select query, this `execute(sql, name)` will call `materialize_transactions`.
4. `materialize_transactions` execute `BEGIN;`
5. `materialize_transactions` -> `connection.begin_db_transaction` -> `connection.begin_db_transaction` -> execute("BEGIN", "TRANSACTION")
6. back to the `execute(sql, name)` of select query and call `@connection.query(sql)`, which execute select query. 
7. "COMMIT;"

So, from the viewpoint of arproxy(or viewpoint of execute(sql, name)) the order is as follows

1. "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1;" 
2. "BEGIN;"
3. "COMMIT;"

even though the actual query execution order is

1. "BEGIN;"
2. "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1;" 
3. "COMMIT;"

I issued because it looks unexpected behavior.
I'm very happy if there is any good idea to avoid it.
Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions