ActiveRecord::Rollback 在嵌套开始救援块中的行为方式
How ActiveRecord::Rollback behaves in nested begin-rescue blocks
我有以下代码
ActiveRecord::Base.transaction do
begin
account.save
# outer statement
begin
user.save
# inner statement
rescue StandardError
raise ActiveRecord::Rollback
end
rescue StandardError
raise ActiveRecord::Rollback
end
end
如果'inner statement'出现异常,只有'user'回滚吧? 'account' 在那种情况下不会被回滚,不是吗?
在您的代码中只有一个数据库事务,它是全有或全无。回滚事务将回滚该事务中所做的所有更改,无论您在哪里发出回滚。
您也可以嵌套事务,但要注意默认情况下事务会被压缩在一起,因此即使您在第一个事务中添加第二个事务:
ActiveRecord::Base.transaction do
begin
account.save
# outer statement
ActiveRecord::Base.transaction do
begin
user.save
# inner statement
rescue StandardError
raise ActiveRecord::Rollback
end
end
rescue StandardError
raise ActiveRecord::Rollback
end
end
这仍然会导致单个事务,回滚将取消所有更改。
要请求真正的子交易,需要在内部交易中添加request_new: true
:
ActiveRecord::Base.transaction do
begin
account.save
# outer statement
ActiveRecord::Base.transaction(require_new: true) do
begin
user.save
# inner statement
rescue StandardError
raise ActiveRecord::Rollback
end
end
rescue StandardError
raise ActiveRecord::Rollback
end
end
但是,目前唯一支持真正嵌套事务的数据库是 MS-SQL。 Rails 目前使用保存点处理此问题 - 所以不要被日志混淆。
我有以下代码
ActiveRecord::Base.transaction do
begin
account.save
# outer statement
begin
user.save
# inner statement
rescue StandardError
raise ActiveRecord::Rollback
end
rescue StandardError
raise ActiveRecord::Rollback
end
end
如果'inner statement'出现异常,只有'user'回滚吧? 'account' 在那种情况下不会被回滚,不是吗?
在您的代码中只有一个数据库事务,它是全有或全无。回滚事务将回滚该事务中所做的所有更改,无论您在哪里发出回滚。
您也可以嵌套事务,但要注意默认情况下事务会被压缩在一起,因此即使您在第一个事务中添加第二个事务:
ActiveRecord::Base.transaction do
begin
account.save
# outer statement
ActiveRecord::Base.transaction do
begin
user.save
# inner statement
rescue StandardError
raise ActiveRecord::Rollback
end
end
rescue StandardError
raise ActiveRecord::Rollback
end
end
这仍然会导致单个事务,回滚将取消所有更改。
要请求真正的子交易,需要在内部交易中添加request_new: true
:
ActiveRecord::Base.transaction do
begin
account.save
# outer statement
ActiveRecord::Base.transaction(require_new: true) do
begin
user.save
# inner statement
rescue StandardError
raise ActiveRecord::Rollback
end
end
rescue StandardError
raise ActiveRecord::Rollback
end
end
但是,目前唯一支持真正嵌套事务的数据库是 MS-SQL。 Rails 目前使用保存点处理此问题 - 所以不要被日志混淆。