1

I am using Drupal behind a reverse proxy/cache layer (e.g. Cloud Front/ Akamai) and sometimes the service goes quite slow (so I get a Gateway timeout, for reasons such as too many people are using the servers) or a something bad happens in the server farm (docker micro-architecture) and so I get a 502 Bad Gateway.

Do we know if a database transaction will roll back in such cases? This is especially relevant when doing 800+ entity updates via the Batch API.

E.g. (based off mock code: https://www.drupal.org/docs/drupal-apis/database-api/database-transactions)


$transaction = $connection->startTransaction();

try {
  // Do some thing that writes to the database.
  $entity = create_some_entity();
  $entity->save();

  // Pretend a 502 Bad Gateway or Gateway timeout happened here.

  // Do another database write that depends upon the first.
  $dependent_entity = update_dependent_entity($entity->id());
  $dependent_entity->save();
}
catch (\Exception $e) {
  // There was an error in writing to the database, so the database is rolled back
  // to the state when the transaction was started.
  // Not sure if catching an exception will do anything here.
  // (since no exception is expected)
  $transaction->rollBack();
}

// Commit the transaction by unsetting the $transaction variable.
unset($transaction);

1 Answer 1

2

A transaction is only rolled back when Transaction::rollBack() is explicitly called. In case of time outs, that doesn't happen.
Actually, in that case, the database changes aren't even committed, since that only happens when Transaction::__destruct() is called.

public function __destruct() {
  // If we rolled back then the transaction would have already been popped.
  if (!$this->rolledBack) {
    $this->connection->popTransaction($this->name);
  }
}
5
  • What about in the case of the user (web browser) disconnecting or the reverse proxy disconnecting (so PHP has not timed out) Apr 12, 2022 at 9:46
  • If the server is set to wait for data from a database connection less than the time required for PHP to time out, the transaction should be rolled-back (assuming that a database connection timeout causes a PHP exception). Otherwise, PHP will time out waiting for a reply that never comes back (and no exception is raised). Also, since it's batch processing, when the browser loses the connection with the server, the batch processing is interrupted.
    – apaderno
    Apr 12, 2022 at 14:54
  • These statements seem to suggest that transaction will be rolled back in the event of PHP process crashing or the network connection failing between PHP and the MySQL server This is a safety measure to help avoid inconsistency in the cases where the script terminates unexpectedly--if you didn't explicitly commit the transaction, then it is assumed that something went awry, so the rollback is performed for the safety of your data. (php.net/manual/en/pdo.transactions.php). [...] May 9, 2022 at 3:26
  • That means if your session disconnects for any reason, either by choice, or else because an error occurs like the network connection fails, etc., then a transaction in progress is rolled back. (dba.stackexchange.com/a/60005), I know the transaction will be rolled back if connection breaks before commiting. (dba.stackexchange.com/q/215579) If you have autocommit disabled, any non-commited transaction is always rolled back at the end of the session. (stackoverflow.com/a/65213497/5150644) May 9, 2022 at 3:26
  • So then am i right to suggest Drupal does rollback in this case (PHP error or connection dropped)? Also does your answer, answer in the affirmative? (the transaction is essentially 'rolled back' as the statements are never committed in the first place) ? May 9, 2022 at 3:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.