Hi, Grégoire Paris here!
I'm a maintainer on Doctrine projects and today, I'd like to talk to you
about something we would like to propose.
We have found that PDO has a method called PDO::inTransaction() that we
would like to mimic in the API of doctrine/dbal, a database abstraction
layer many of you may already know. We would like to implement this in
driver abstraction classes, so that we can call the new method from our
existing Connection::isTransactionActive() method.
Connection::isTransactionActive() currently relies on a counter, but as
you may know, this is not foolproof because of how some RDBMS like MySQL
will implicitly commit transactions when DDL is involved. In such cases,
the method will return true when it should really return false.
Our problem is, we are missing an API similar to PDO::inTransaction()
for the mysqli driver.
We would like to contribute that API and Sergei Morozov already worked
on a patch. It is available at
https://github.com/php/php-src/compare/PHP-8.0...morozov:mysqli-in-transaction
,
and can be tested as follows:
<?php
$conn = mysqli_connect('127.0.0.1', 'root', '', 'doctrine');
if (!$conn) {
exit(1);
}
echo 'Testing commit, procedural interface:', PHP_EOL;
var_dump(mysqli_in_transaction($conn));
mysqli_begin_transaction($conn);
var_dump(mysqli_in_transaction($conn));
mysqli_commit($conn);
var_dump(mysqli_in_transaction($conn));
echo PHP_EOL;
echo 'Testing rollback, OO interface:', PHP_EOL;
var_dump($conn->in_transaction());
$conn->begin_transaction();
var_dump($conn->in_transaction());
$conn->rollback();
var_dump($conn->in_transaction());
echo PHP_EOL;
echo 'Testing DDL:', PHP_EOL;
mysqli_query($conn, 'DROP TABLE IF EXISTS foo');
mysqli_begin_transaction($conn);
var_dump(mysqli_in_transaction($conn));
mysqli_query($conn, 'CREATE TABLE foo(id INT)');
var_dump(mysqli_in_transaction($conn));
echo PHP_EOL;
Testing commit, procedural interface:
bool(false)
bool(true)
bool(false)Testing rollback, OO interface:
bool(false)
bool(true)
bool(false)Testing DDL:
bool(true)
bool(false)
Would it be OK for us to go ahead and contribute this?
The DBAL RFC can be found at https://github.com/doctrine/dbal/issues/4616
Best regards,
--
Grégoire Paris
What about OCI8 driver? That’s also included in core.
Also a sidermark: SQLSrv and IBMDB2 are not part of core, but situation should be checked in those as well, since they are supported in DBA tooL
Powered by Mailbutler https://www.mailbutler.io/?utm_source=watermark&utm_medium=email&utm_campaign=watermark-essential-email, the email extension that does it all
Hi,
There is the SQLGetConnectAttr method and the SQL_ATTR_AUTOCOMMIT attribute
(part of the ISO 92 standard) which should allow detecting the transaction
state at the driver level. This API used by the SQL Server extensions (to
manage the transaction) and it also seems to be available for Oracle and
IBM DB2 drivers as well.
I'd like to start with the mysqli driver specifically because:
- MySQL is one of the DB platforms that doesn't support in transactions.
- It's much more widely used with PHP than Oracle.
We can attempt to implement this functionality in different DB extensions
independently since they don't depend on each other.
What about OCI8 driver? That’s also included in core.
Also a sidermark: SQLSrv and IBMDB2 are not part of core, but situation
should be checked in those as well, since they are supported in DBA tooLPowered by Mailbutler
https://www.mailbutler.io/?utm_source=watermark&utm_medium=email&utm_campaign=watermark-essential-email,
the email extension that does it all
--
Sergei Morozov