}
/* }}} */
+
+static zend_bool pdo_is_in_transaction(pdo_dbh_t *dbh) {
+ if (dbh->methods->in_transaction) {
+ return dbh->methods->in_transaction(dbh);
+ }
+ return dbh->in_txn;
+}
+
/* {{{ Initiates a transaction */
PHP_METHOD(PDO, beginTransaction)
{
PDO_CONSTRUCT_CHECK;
- if (dbh->in_txn) {
+ if (pdo_is_in_transaction(dbh)) {
zend_throw_exception_ex(php_pdo_get_exception(), 0, "There is already an active transaction");
RETURN_THROWS();
}
PDO_CONSTRUCT_CHECK;
- if (!dbh->in_txn) {
+ if (!pdo_is_in_transaction(dbh)) {
zend_throw_exception_ex(php_pdo_get_exception(), 0, "There is no active transaction");
RETURN_THROWS();
}
PDO_CONSTRUCT_CHECK;
- if (!dbh->in_txn) {
+ if (!pdo_is_in_transaction(dbh)) {
zend_throw_exception_ex(php_pdo_get_exception(), 0, "There is no active transaction");
RETURN_THROWS();
}
PDO_CONSTRUCT_CHECK;
- if (!dbh->methods->in_transaction) {
- RETURN_BOOL(dbh->in_txn);
- }
-
- RETURN_BOOL(dbh->methods->in_transaction(dbh));
+ RETURN_BOOL(pdo_is_in_transaction(dbh));
}
/* }}} */
// DDL will issue an implicit commit
$db->exec(sprintf('DROP TABLE IF EXISTS test_commit'));
$db->exec(sprintf('CREATE TABLE test_commit(id INT) ENGINE=%s', MySQLPDOTest::detect_transactional_mysql_engine($db)));
- if (true !== ($tmp = $db->commit())) {
- printf("[002] No commit allowed? [%s] %s\n",
- $db->errorCode(), implode(' ', $db->errorInfo()));
+ try {
+ $db->commit();
+ $failed = false;
+ } catch (PDOException $e) {
+ $failed = true;
+ }
+ if (!$failed) {
+ printf("[002] Commit should have failed\n");
}
// pdo_transaction_transitions should check this as well...
const END = ['COMMIT', 'ROLLBACK'];
$db = MySQLPDOTest::factory();
-// $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // mysql does not support
-for ($b = 0; $b < count(BEGIN); $b++) {
- for ($e = 0; $e < count(END); $e++) {
+// $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // mysql does not support
+foreach (BEGIN as $begin) {
+ foreach (END as $end) {
foreach (['exec', 'query', 'execute'] as $w) {
- foreach ([BEGIN[$b], END[$e]] as $command) {
+ foreach ([$begin, $end] as $command) {
switch ($w) {
case 'exec':
$db->exec($command);
}
}
}
+echo "\n";
+
+// Mixing PDO transaction API and explicit queries.
+foreach (END as $end) {
+ $db->beginTransaction();
+ var_dump($db->inTransaction());
+ $db->exec($end);
+ var_dump($db->inTransaction());
+}
+
+$db->exec('START TRANSACTION');
+var_dump($db->inTransaction());
+$db->rollBack();
+var_dump($db->inTransaction());
+$db->exec('START TRANSACTION');
+var_dump($db->inTransaction());
+$db->commit();
+var_dump($db->inTransaction());
+echo "\n";
+
+// DDL query causes an implicit commit.
+$db->beginTransaction();
+var_dump($db->inTransaction());
+$db->exec('DROP TABLE IF EXISTS test');
+var_dump($db->inTransaction());
+
+// We should be able to start a new transaction after the implicit commit.
+$db->beginTransaction();
+var_dump($db->inTransaction());
+$db->commit();
+var_dump($db->inTransaction());
?>
--EXPECT--
bool(false)
bool(true)
bool(false)
+
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+
+bool(true)
+bool(false)
+bool(true)
+bool(false)
$db->query('DROP TABLE IF EXISTS test2');
$db->query('CREATE TABLE test2(id INT)');
$num++;
- $db->rollBack();
- $row = $db->query('SELECT COUNT(*) AS _num FROM test')->fetch(PDO::FETCH_ASSOC);
- if ($row['_num'] != $num)
- printf("[002] ROLLBACK should have no effect because of the implicit COMMIT
- triggered by DROP/CREATE TABLE\n");
-
+ try {
+ $db->rollBack();
+ $failed = false;
+ } catch (PDOException $e) {
+ $failed = true;
+ }
+ if (!$failed) {
+ printf("[003] Rollback should have failed\n");
+ }
$db->query('DROP TABLE IF EXISTS test2');
$db->query('CREATE TABLE test2(id INT) ENGINE=MyISAM');