Rails 7.1 Active Record Transaction on return, break and throw
In the latest Rails, a significant change has been made to the behaviour of transactions. Specifically, using return
, break
, or throw
statements will no longer trigger an automatic rollback of the transaction.
In Rails 6.1 use of return
, break
, and throw
statements within transactions has been deprecated.
For example in the below code
class User < ApplicationRecord
def self.transaction_with_return
User.transaction do
User.create(email: "test@example.com",name: "Test")
return
User.create(email: "test1@example.com",name: "Test1")
end
puts User.count
end
end
If we run the method User.transaction_with_return
, only 1 user is created as the transaction is exited with the return keyword and the same outcome occurs whether we use the break
or throw
keyword.
The rationale behind this deprecation was closely tied to the behaviour of the timeout
library in Ruby 2.3.
In Ruby 2.3, the timeout
library utilized the throw
mechanism to exit a transaction silently if no second argument (specifically, an Exceptional Class) was provided.
However, with the release of timeout version 0.4.0, it reverted to raising exceptions in such cases.
With this change, ActiveRecord has reinstated its previous behaviour prior to version 6.1, where transactions will be committed even if return
, break
, or throw
statements are used.
But now in Rails 7.1 transactions will not exit with the return
, break
or throw
keyword. This was the original behaviour of Rails before version 6.1
Let's take the example again
class User < ApplicationRecord
def self.transaction_with_return
User.transaction do
User.create(email: "test@example.com",name: "Test")
return
User.create(email: "test1@example.com",name: "Test1")
end
puts User.count
end
end
So now User.transaction_with_return
, will create two users instead of one.
This is the default behaviour in Rails 7.1 but if you want it version between 7.1 and 6.1 you can get by
Rails.application.config.active_record.commit_transaction_on_non_local_return = true
Related Links