Problem/Motivation

This is a follow-up to #3569316: Client connection ($clientConnection) must be of type object, null given when deleting a node, not a confirmed regression introduced by that issue. That fix added processing of pending post-transaction callbacks to TransactionManagerBase::commitAll(). However, Connection::commitAll() still calls the manager only when inTransaction() is true.

An explicit Transaction::commitOrRelease() or Transaction::rollBack() can end the database transaction while its post-transaction callbacks remain pending until the Transaction object is destroyed. If that object is still alive when the connection is closed or the shutdown handler runs, the caller skips the manager and therefore skips the callback processing added by #3569316.

This affects deferred cache tag invalidation and other post-transaction callbacks. Data can be saved successfully while a subsequent request still reads stale cached data. In an application-level reproduction, a newly created membership was stored correctly, but the next request was denied access because the permissions cache had not been invalidated.

The issue was reproduced on Drupal 11.4.8 with PHP 8.4.26 and Xdebug 3.5.3 in develop mode in the web server. The kernel regression retains the transaction object explicitly and does not require Xdebug or contributed modules.

Steps to reproduce

Proposed resolution

Remove the inTransaction() condition from Connection::commitAll(), retaining the existing method_exists() compatibility check. The transaction manager already processes pending callbacks when its stack is empty. This allows all three cleanup entry points to complete callbacks while the connection is still valid, including after an explicit commit or rollback.

No additional cache flush, retry, exception suppression, permissions override or alternative transaction implementation is introduced. The attached test covers all three transaction outcomes through all three cleanup entry points, actual cache tag checksums and repeated cleanup followed by transaction destruction.

Remaining tasks

  • Review and run the patch against the current target branch and the supported database-driver matrix in Drupal Core CI. The supplied patch is based on and locally verified against Drupal 11.4.8.
  • Track response-before-shutdown timing separately. This patch completes callbacks at the existing cleanup boundary; it does not move invalidation before the HTTP response is sent and does not guarantee that a parallel PHP-FPM follow-up request cannot arrive before shutdown. This separate concern is also described in comment #11 of #3569316: Client connection ($clientConnection) must be of type object, null given when deleting a node.
  • Do not treat this as a blanket fix for every destruction-order failure. The reproduced skipped-callback condition and application workflow are covered; unrelated PHPUnit CLI shutdown failures and other PHP/database combinations require their own evidence.

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3628674

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:

Comments

zcht created an issue. See original summary.

zcht’s picture

Assigned: zcht » Unassigned
Status: Active » Needs review
StatusFileSize
new662 bytes
new3.38 KB
quietone’s picture

Version: 11.4.x-dev » main
Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs merge request

Hi, thanks for the patch!

Issues for Drupal core should be targeted to the 'main' branch, our primary development branch. Changes are made on the main branch first, and are then back ported as needed according to the Core change policies. The version the problem was discovered on should be stated in the issue summary Problem/Motivation section. Thanks.

This issue needs a merge request to be ready for review.

The steps to reproduce here are not necessary, those steps are automated by our testing processes. Therefore I have removed the steps to reproduce. Also, I have removed unnecessary stuff from the issue summary.

I removed the step about confirming which branches to backport because the is done by the committer.

zcht’s picture

Thanks for your feedback, quietone . I haven't worked with the core processes before. I've only tested them extensively locally and wasn't quite sure how best to go about it. That's why I tried to describe everything in as much detail as possible and included a test for you to check.

I’ll see if I can get it to work the way you described. In my opinion, this is unfortunately a pretty serious bug - one I spent four days trying to find and only discovered by chance. This could really break a lot of Drupal instances that have already been updated and are already using the change in the issue I mentioned above in production environments.

zcht changed the visibility of the branch 3628674-complete-pending-post-transaction to hidden.

zcht’s picture

Status: Needs work » Needs review