Problem/Motivation

Currently if a DB supporting transactions is used then on entity save the transaction will be committed after the SqlContentEntityStorage::save() method is finished and the transaction object is out of scope so that its destructor is executed. This means that all the hooks will be fired before the transaction is committed including the update hook.

If you are building a system where a lock for the entity is being created in the presave hook and should be released after the entity is saved then using the update hook while in transaction might lead to race conditions e.g. by releasing the lock and a concurrent request trying to get a lock and load the entity with the expectation that the entity will be the newly saved entity by the other process. However this will not be the case if it happens that the lock is retrieved by the concurrent process just before the transaction is committed in which case the concurrent process will load the entity in its previous state.

In order to overcome this we need a hook that will be fired after the transaction is committed.

Proposed resolution

In SqlContentEntityStorage::save() commit the transaction and start a new one inside which invoke an entity post transactional hook.

Remaining tasks

Decide between #25 and #33 for proposed solution
Add tests
Review

User interface changes

API changes

Data model changes

Issue fork drupal-2892654

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

hchonov created an issue. See original summary.

hchonov’s picture

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

pclaitte’s picture

Hello

Thanks for the patch. You save my day.

I was into a hook_file_update and I wanted to access file_usage but she was was not yet updated because transaction had not been commited. I have moved my code into the new hook_ENTITY_TYPE_post_transaction and it works perfectly.

Thanks a lot

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

effulgentsia’s picture

joseph.olstad’s picture

I need this for doing metatag overrides , easier if the custom stuff I want to do is on post save.

joseph.olstad’s picture

patch still applies, but with fuzz, could use a reroll.

I'm going to use it.

joseph.olstad’s picture

Status: Needs review » Needs work

I applied this core patch, after applying it I was unable to do a cache rebuild with drush.
So I reverted it.
we are using drush 9.2.3

In BootstrapHook.php line 32:

  Bootstrap failed.
hchonov’s picture

I don't think that your problems are because of the patch. I don't see how it could be affecting anything, as it only adds functionality in the entity's saving process. You've mentioned that you need a re-roll. Do you mind uploading it?

Also please share the complete error message / backtrace.

joseph.olstad’s picture

I made no modifications to the patch.

sorry I don't have time right now to provide more in dept analysis.
reverted it for now. Might try it again later however I discovered that I did not need the patch.

For now we're using hook_presave instead and it does the job for us.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Wim Leers’s picture

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

jitendrapurohit’s picture

The patch doesn't apply on the latest drupal 9.3. Here's the updated patch.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Megha_kundar’s picture

Updated patch file extension from .diff to .patch

Megha_kundar’s picture

Megha_kundar’s picture

Megha_kundar’s picture

Status: Needs work » Needs review
masterperoo’s picture

Confirmed - this saved my day as well!

Im my case - there are field values that need updating after the entity has been saved/inserted and is already visible to other modules.
Without this hook - I am facing splitting every entity save into separate chunks.

the patch is a life saver!

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

joachim’s picture

Status: Needs review » Closed (outdated)
+++ b/core/lib/Drupal/Core/Entity/entity.api.php
@@ -1225,6 +1225,36 @@ function hook_ENTITY_TYPE_update(\Drupal\Core\Entity\EntityInterface $entity) {
+ * Respond to updates to an entity.

This needs more detail.

Also, it should say that this hook is only available to entities using SQL storage.

joachim’s picture

Status: Closed (outdated) » Needs work

Oops. wrong status

Mykola Dolynskyi’s picture

Core firing hook_entity_insert() and hook_entity_insert() before transaction is finished may be not so bad, but bad there are no same hooks to be fired after transaction finished and no tables locked!

kunal_sahu made their first commit to this issue’s fork.

kunal_sahu’s picture

Status: Needs work » Needs review
FileSize
1.09 KB

The above patch is committing the transaction and then starting a new one inside the if block that checks if the parent save() method has returned true. This ensures that the post transactional hook is only invoked if the entity save operation was successful.
The moduleHandler is used to invoke the entity_post_transactional_save hook, which should be implemented by any modules that need to perform actions that are not part of the main entity save transaction.

Please review. Thanks

smustgrave’s picture

Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative, +Needs issue summary update, +Needs tests

@kunal_sahu can you explain why your solution is a better approach then the previous patches please.

Added to the remaining tasks decision needs to be made between #23 and #33.

Test coverage will be needed either wya.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.