aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/transaction_callbacks_test.rb
Commit message (Collapse)AuthorAgeFilesLines
* Enable `Layout/EmptyLinesAroundAccessModifier` copRyuta Kamizono2019-06-131-1/+0
| | | | | | | | | | | 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.
* Should attempt `committed!`/`rolledback!` to all enrolled records in the ↵Ryuta Kamizono2019-05-071-5/+51
| | | | | | | | | | | | | | | | | | | | | | 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.
* Should take the record's state of first action in the transactionRyuta Kamizono2019-04-301-0/+2
| | | | | | | | | | | | | | | | 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.
* Don't expose `add_to_transaction`Ryuta Kamizono2019-04-141-3/+3
| | | | | | | | | | | | | | `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`.
* Don't call after_commit callbacks despite a record isn't savedRyuta Kamizono2019-04-121-0/+26
| | | | | | | | | | | 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.
* Add `after_save_commit` callback as shortcut for `after_commit :hook, on: [ ↵David Heinemeier Hansson2019-04-021-0/+12
| | | | :create, :update ]`. (#35804)
* Always add records to parent of nested transactionEugene Kenny2018-11-071-0/+11
| | | | | | | | | | | | | | | | | | | 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]
* Fix `save` in `after_create_commit` won't invoke extra `after_create_commit`Ryuta Kamizono2018-06-041-0/+9
| | | | | | | | | | | | | | | 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.
* `record.destroy` on new record won't invoke after create commit callbacksRyuta Kamizono2018-06-031-0/+8
| | | | Fixes #32806.
* Fix logic on disabling commit callbacksBrian Durand2018-05-041-0/+20
| | | | 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.
* Fix that after commit callbacks on update does not triggered when optimistic ↵Ryuta Kamizono2018-03-061-0/+22
| | | | | | | | | | | | | | | | | | 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.
* Use assert_empty and assert_not_emptyDaniel Colson2018-01-251-4/+4
|
* Use assert_predicate and assert_not_predicateDaniel Colson2018-01-251-4/+4
|
* Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-191-0/+2
|
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
|
* Prioritize checking `:on` actions before `:if` for transaction callbacksErol Fornoles2017-02-211-0/+40
|
* Emulate db trigger behaviour for after_commit :destroy, :updateStefan Budeanu2016-12-091-0/+45
| | | | | | 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.
* Add more rubocop rules about whitespacesRafael Mendonça França2016-10-291-6/+6
|
* Add three new rubocop rulesRafael Mendonça França2016-08-161-20/+20
| | | | | | | | Style/SpaceBeforeBlockBraces Style/SpaceInsideBlockBraces Style/SpaceInsideHashLiteralBraces Fix all violations in the repository.
* code gardening: removes redundant selfsXavier Noria2016-08-081-1/+1
| | | | | | | | | 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.
* Add `Style/EmptyLines` in `.rubocop.yml` and remove extra empty linesRyuta Kamizono2016-08-071-1/+0
|
* applies remaining conventions across the projectXavier Noria2016-08-061-1/+0
|
* modernizes hash syntax in activerecordXavier Noria2016-08-061-6/+6
|
* applies new string literal convention in activerecord/testXavier Noria2016-08-061-12/+12
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* Fix corrupt transaction state caused by `before_commit` exceptionsJeremy Daer2016-02-011-0/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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!
* Introduce after_{create,update,delete}_commit callbacksGenadi Samokovarov2015-12-061-3/+3
| | | | | | | | | | | | | | | | 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
* Closes rails/rails#18864: Renaming transactional fixtures to transactional testsBrandon Weiss2015-03-161-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Fix before_commit when updating a record on the callbackArthur Neves2015-03-141-0/+22
|
* Rename testsArthur Neves2015-02-241-4/+4
|
* Add before_commitArthur Neves2015-02-241-2/+3
| | | | [fixes #18903]
* Add transaction callbacks that wont enroll to the transaction.Arthur Neves2015-02-241-0/+59
| | | | | | | | | 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]
* TransactionManager should call rollback recordsArthur Neves2015-01-201-1/+1
|
* after_commit runs after transactions with non-joinable parentsbrainopia2015-01-161-14/+13
| | | | | | 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`.
* Change transaction callbacks to not swallowing errors.Rafael Mendonça França2015-01-041-41/+0
| | | | | | | | 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.
* Make error message clearer that :on requires a symbol, not a stringCarol Nichols2014-12-071-0/+4
| | | | | | | | | | | | | | 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.
* Add option to stop swallowing errors on callbacks.Arthur Neves2014-08-181-0/+76
| | | | | | | | | | | | | | | 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]
* Fix regression on after_commit in nested transactions.Arthur Neves2014-08-151-0/+13
| | | | | | | | | 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]
* Make sure transaction state resets after commitArthur Neves2014-02-031-0/+15
| | | | [fixes #12566]
* Do not set up a variable used only in two testsCarlos Antonio da Silva2014-01-161-15/+18
| | | | | Just create a local variable whenever we need the record, rather than doing an extra find for every test on the setup method.
* No need for instance vars on single testsCarlos Antonio da Silva2014-01-161-8/+8
|
* Cleanup duplicated setup of callbacks in transactions testsCarlos Antonio da Silva2014-01-161-48/+19
|
* No need to use #send with public methodsCarlos Antonio da Silva2014-01-161-10/+10
|
* Make AR::Base#touch fire the after_commit and after_rollback callbacksHarry Brundage2014-01-161-1/+46
|
* Don't rewrite AR connection#commit_db_transaction method globallyAkira Matsuda2013-07-291-4/+4
|
* Revert "Merge pull request #6226 from gnufied/master"Rafael Mendonça França2013-04-101-32/+0
| | | | | | | | | | | | | 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
* Deprecate #connection in favour of accessing it via the classBen Moss2013-03-091-4/+4
| | | | | This allows end-users to have a `connection` method on their models without clashing with ActiveRecord internals.
* multiple actions for :on option with `after_commit` and `after_rollback`Yves Senn2013-02-211-0/+35
| | | | Closes #988.
* Don't call after_commit when creating through an association and save fails, ↵James Miller2013-02-131-0/+27
| | | | fixes #5802
* validate :on option on after_commit and after_rollback callbacksPascal Friederich2012-12-261-0/+8
|