Hi internals,

Since PHP 8.0, PDO fully supports MySQL transactions -- this means that
inTransaction() will report the actual connection transaction state, as
opposed to an emulated (incorrect) transaction state tracked by PDO itself.

This has two primary effects: PDO is aware of transactions created without
going through it's APIs (e.g. by manually issuing a START TRANSACTION
query) and is aware of implicit commits (see
https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html for more
information).

The latter means that code like

$pdo->beginTransaction()
$pdo->exec('DROP TABLE foobar'); // Implicitly commits transaction
$pdo->exec('DROP TABLE barfoo'); // Transaction not active anymore
$pdo->commit(); // Throws because no transaction active

now throws an exception, because commit() is called without an active
transaction. It's possible to use if ($pdo->inTransaction())
$pdo->commit(); if you don't care about the lack of active transaction.

I believe this behavior is correct, but I could see an argument made in
favor of always allowing commit() calls (but not rollBack() calls) even if
there is no active transaction. That would change the meaning of commit()
from "commit an active transaction" towards "commit if an active
transaction exists".

Any opinions on that?

Regards,
Nikita

Reply via email to