| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
| |
We sometimes say "✂️ newline after `private`" in a code review (e.g.
https://github.com/rails/rails/pull/18546#discussion_r23188776,
https://github.com/rails/rails/pull/34832#discussion_r244847195).
Now `Layout/EmptyLinesAroundAccessModifier` cop have new enforced style
`EnforcedStyle: only_before` (https://github.com/rubocop-hq/rubocop/pull/7059).
That cop and enforced style will reduce the our code review cost.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
transaction
Currently, `committed!`/`rolledback!` will only be attempted for the
first enrolled record in the transaction, that will cause some
problematic behaviors.
The first one problem, `clear_transaction_record_state` won't be called
even if the transaction is finalized except the first enrolled record.
This means that de-duplicated records in the transaction won't refer
latest state (e.g. won't happen rolling back record state).
The second one problem, the enrolled order is not always the same as the
order in which the actions actually happened, the first enrolled record
may succeed no actions (e.g. `destroy` has already succeeded on another
record during `before_destroy`), it will lose to fire any transactional
callbacks.
To avoid both problems, we should attempt `committed!`/`rolledback!` to
all enrolled records in the transaction.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the same id's records are saved and/or destroyed in the transaction,
commit callbackes will only run for the first enrolled record.
https://github.com/rails/rails/blob/a023e2180093ebc517a642aaf21f3c7241c67657/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb#L115-L119
The regression #36132 is caused due to #35920 changed the enrollment
order that the first action's record will be enrolled to last in the
transaction.
We could not change the the enrollment order as long as someone depends
on the enrollment order.
Fixes #36132.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`add_to_transaction` was added at da840d1, but it should not be called
by except internal, since `remember_transaction_record_state` should be
called only once before saving.
And also, currently `add_to_transaction` doesn't always add the record
to transaction since da8de91, that is the reason hard to use that even
in internal.
Even if `add_to_transaction` ensure to add the record to transaction,
that is an internal concern, people don't need to explicitly call
`add_to_transaction`.
|
|
|
|
|
|
|
|
|
|
|
| |
Regardless of a record isn't saved (e.g. validation is failed),
`after_commit` / `after_rollback` callbacks are invoked for now.
To fix the issue, this adds a record to the current transaction only
when a record is actually saved.
Fixes #29747.
Closes #29833.
|
|
|
|
| |
:create, :update ]`. (#35804)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a record with transactional callbacks is saved, it's attached to
the current transaction so that the callbacks can be run when the
transaction is committed. Records can also be added manually with
`add_transaction_record`, even if they have no transactional callbacks.
When a nested transaction is committed, its records are transferred to
the parent transaction, as transactional callbacks should only be run
when the outermost transaction is committed (the "real" transaction).
However, this currently only happens when the record has transactional
callbacks, and not when added manually with `add_transaction_record`.
If a record is added to a nested transaction, we should always attach it
to the parent transaction when the nested transaction is committed,
regardless of whether it has any transactional callbacks.
[Eugene Kenny & Ryuta Kamizono]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since a record is already persisted in `after_create_commit`, so `save`
should invoke only `after_update_commit`.
This bug is caused by depending on `@_start_transaction_state` for
rollback to consider whether it was `new_record` before being committed.
If after commit callbacks caused another commit, the state before
last commit is no longer `new_record`.
Fixes #32831.
Closes #18367.
Closes #31106.
|
|
|
|
| |
Fixes #32806.
|
|
|
|
| |
Commit callbacks are intentionally disabled when errors occur when calling the callback chain in order to reset the internal record state. However, the implicit order of operations on the logic for checking if callbacks are disabled is wrong. The result is that callbacks can be unexpectedly when errors occur in transactions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
locking is enabled
This issue is caused by `@_trigger_update_callback` won't be updated due
to `_update_record` in `Locking::Optimistic` doesn't call `super` when
optimistic locking is enabled.
Now optimistic locking concern when updating is supported by
`_update_row` low level API, therefore overriding `_update_record` is no
longer necessary.
Removing the method just fix the issue.
Closes #29096.
Closes #29321.
Closes #30823.
|
| |
|
| |
|
| |
|
|
|
|
|
| |
This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing
changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
|
| |
|
| |
|
|
|
|
|
|
| |
Race conditions can occur when an ActiveRecord is destroyed
twice or destroyed and updated. The callbacks should only be
triggered once, similar to a SQL database trigger.
|
| |
|
|
|
|
|
|
|
|
| |
Style/SpaceBeforeBlockBraces
Style/SpaceInsideBlockBraces
Style/SpaceInsideHashLiteralBraces
Fix all violations in the repository.
|
|
|
|
|
|
|
|
|
| |
A few have been left for aesthetic reasons, but have made a pass
and removed most of them.
Note that if the method `foo` returns an array, `foo << 1`
is a regular push, nothing to do with assignments, so
no self required.
|
| |
|
| |
|
| |
|
|
|
|
|
| |
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a `before_commit` callback raises, the database is rolled back but
AR's record of the current transaction is not, leaving the connection in
a perpetually broken state that affects all future users of the
connection: subsequent requests, jobs, etc. They'll think a transaction
is active when none is, so they won't BEGIN on their own. This manifests
as missing `after_commit` callbacks and broken ROLLBACKs.
This happens because `before_commit` callbacks fire before the current
transaction is popped from the stack, but the exception-handling path
they hit assumes that the current transaction was already popped. So the
database ROLLBACK is issued, but the transaction stack is left intact.
Common cause: deadlocked `#touch`, which is now implemented with
`before_commit` callbacks.
What's next:
* We shouldn't allow active transaction state when checking in or out
from the connection pool. Verify that conns are clean.
* Closer review of txn manager sad paths. Are we missing other spots
where we'd end up with incorrect txn state? What's the worst that can
happen if txn state drifts? How can we guarantee it doesn't and
contain the fallout if it does?
Thanks for @tomafro for expert diagnosis!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Those are actually shortcuts for `after_commit`.
Before:
after_commit :add_to_index_later, on: :create
after_commit :update_in_index_later, on: :update
after_commit :remove_from_index_later, on: :destroy
After:
after_create_commit :add_to_index_later
after_update_commit :update_in_index_later
after_destroy_commit :remove_from_index_later
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I’m renaming all instances of `use_transcational_fixtures` to
`use_transactional_tests` and “transactional fixtures” to
“transactional tests”.
I’m deprecating `use_transactional_fixtures=`. So anyone who is
explicitly setting this will get a warning telling them to use
`use_transactional_tests=` instead.
I’m maintaining backwards compatibility—both forms will work.
`use_transactional_tests` will check to see if
`use_transactional_fixtures` is set and use that, otherwise it will use
itself. But because `use_transactional_tests` is a class attribute
(created with `class_attribute`) this requires a little bit of hoop
jumping. The writer method that `class_attribute` generates defines a
new reader method that return the value being set. Which means we can’t
set the default of `true` using `use_transactional_tests=` as was done
previously because that won’t take into account anyone using
`use_transactional_fixtures`. Instead I defined the reader method
manually and it checks `use_transactional_fixtures`. If it was set then
it should be used, otherwise it should return the default, which is
`true`. If someone uses `use_transactional_tests=` then it will
overwrite the backwards-compatible method with whatever they set.
|
| |
|
| |
|
|
|
|
| |
[fixes #18903]
|
|
|
|
|
|
|
|
|
| |
Add after_commit_without_transaction_enrollment and
after_rollback_without_transaction_enrollment private callbacks so we
can create after_commit and after_rollback callbacks without having the
records automatic enrolled in the transaction.
[fixes #18904]
|
| |
|
|
|
|
|
|
| |
after_commit callbacks run after committing a transaction whose parent
is not `joinable?`: un-nested transactions, transactions within test
cases, and transactions in `console --sandbox`.
|
|
|
|
|
|
|
|
| |
Before this change any error raised inside a transaction callback
are rescued and printed in the logs.
Now these errors are not rescue anymore and just bubble up,
as the other callbacks.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The validation added in 5a3dc8092d19c816b0b1203945639cb91d065847 will
reject values for the `:on` option for after_commit and after_rollback
callbacks that are string values like `"create"`.
However, the error message says ":on conditions for after_commit and
after_rollback callbacks have to be one of create,destroy,update". That
looks like a string value *would* be valid.
This commit changes the error message to say ":on conditions for
after_commit and after_rollback callbacks have to be one of [:create,
:destroy, :update]", making it clearer that symbols are required.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently, Active Record will rescue any errors raised within
after_rollback/after_create callbacks and print them to the
logs. Next versions of rails will not rescue those errors anymore,
and just bubble them up, as the other callbacks.
This adds a opt-in flag to enable that behaviour, of not rescuing
the errors.
Example:
# For not swallow errors in after_commit/after_rollback
config.active_record.errors_in_transactional_callbacks = true
[fixes #13460]
|
|
|
|
|
|
|
|
|
| |
after_commit should not run in nested transactions, however they should
run once the outermost transaction gets committed. This patch fixes the
problem copying the records from the Savepoint to its parent. So the
RealTransaction will have all records that needs to run callbacks on it.
[fixes #16425]
|
|
|
|
| |
[fixes #12566]
|
|
|
|
|
| |
Just create a local variable whenever we need the record, rather than
doing an extra find for every test on the setup method.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit 9bf1a0db4acbbf9e8e6f707250269185224e7efe, reversing
changes made to fed97091b9546d369a240d10b184793d49247dd3.
Conflicts:
activerecord/test/cases/transaction_callbacks_test.rb
Reason: This fix introduces another issue described at #8937, so we are
reverting it to restore the behavior of 3-2-stable.
We will fix both issues when we come out with a better solution
|
|
|
|
|
| |
This allows end-users to have a `connection` method on their models
without clashing with ActiveRecord internals.
|
|
|
|
| |
Closes #988.
|
|
|
|
| |
fixes #5802
|
| |
|