diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php index 1172406e34..cc1728bad7 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php @@ -797,6 +797,13 @@ public function save(EntityInterface $entity) { // Ignore replica server temporarily. db_ignore_replica(); + + // Commit the transaction and fire an after transactional save hook in a + // new transaction. + unset($transaction); + $transaction = $this->database->startTransaction(); + $this->invokeHook('post_transaction', $entity); + return $return; } catch (\Exception $e) { diff --git a/core/lib/Drupal/Core/Entity/entity.api.php b/core/lib/Drupal/Core/Entity/entity.api.php index 5387c7ef7e..fb96633799 100644 --- a/core/lib/Drupal/Core/Entity/entity.api.php +++ b/core/lib/Drupal/Core/Entity/entity.api.php @@ -1024,6 +1024,34 @@ function hook_ENTITY_TYPE_update(Drupal\Core\Entity\EntityInterface $entity) { } /** + * Respond to updates to an entity. + * + * This hook runs once the entity storage has been updated and the database + * transaction has been committed. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object. + * + * @ingroup entity_crud + * @see hook_ENTITY_TYPE_post_transaction() + */ +function hook_entity_post_transaction(Drupal\Core\Entity\EntityInterface $entity) {} + +/** + * Respond to updates to an entity of a particular type. + * + * This hook runs once the entity storage has been updated and the database + * transaction has been committed. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object. + * + * @ingroup entity_crud + * @see hook_entity_post_transaction() + */ +function hook_ENTITY_TYPE_post_transaction(Drupal\Core\Entity\EntityInterface $entity) {} + +/** * Acts when creating a new entity translation. * * This hook runs after a new entity translation object has just been