-
Notifications
You must be signed in to change notification settings - Fork 25
Open
Description
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
Labels
No labels