Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the following PDO transaction is committing?

Tags:

php

pdo

I think the question itself is pretty self-explanatory. The code is given below -

<?php
    $PDO = NULL;
    $pdo_dsn = 'mysql:host=localhost;dbname=pdo_test';
    $pdo_persistence = array( PDO::ATTR_PERSISTENT => true );
    $db_user = 'root';
    $db_pass = '';
    $db_query = "INSERT INTO person(name, address)
                    VALUES ('Mamsi Mamsi', 'Katabon')";

    try
    {
            $PDO = new PDO($pdo_dsn, $db_user, $db_pass, 
                              $pdo_persistence);
    }
    catch(PDOException $e)
    {
            echo "Error occured: ". $e->getMessage();
            die();
    }

    $PDO->setAttribute(PDO::ATTR_ERRMODE, 
                           PDO::ERRMODE_EXCEPTION);
    $PDO->setAttribute(PDO::ATTR_AUTOCOMMIT, false);

    try
    {
            $PDO->beginTransaction();
            $PDO->exec($db_query);

            throw new PDOException('Generated Exception');

            $PDO->commit();
    }
    catch(PDOException $e)
    {
            echo "An error occured while doing a database transaction. The 
            error message is : ".$e->getMessage();

            $PDO->rollBack();
            die();
    }
?>

Even if I am rolling back the transaction inside the catch block, data are still being inserted into the database. Why?

EDIT

I am adding the following few lines from the documentation for further clarification -

Unfortunately, not every database supports transactions, so PDO needs to run in what is known as "auto-commit" mode when you first open the connection. Auto-commit mode means that every query that you run has its own implicit transaction, if the database supports it, or no transaction if the database doesn't support transactions. If you need a transaction, you must use the PDO::beginTransaction() method to initiate one. If the underlying driver does not support transactions, a PDOException will be thrown (regardless of your error handling settings: this is always a serious error condition). Once you are in a transaction, you may use PDO::commit() or PDO::rollBack() to finish it, depending on the success of the code you run during the transaction.

Also, the following lines from this page -

bool PDO::beginTransaction  ( void  )

Turns off autocommit mode. While autocommit mode is turned off, changes made to the database via the PDO object instance are not committed until you end the transaction by calling PDO::commit(). Calling PDO::rollBack() will roll back all changes to the database and return the connection to autocommit mode.

Some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction. The implicit COMMIT will prevent you from rolling back any other changes within the transaction boundary.

like image 614
MD Sayem Ahmed Avatar asked Jul 26 '10 03:07

MD Sayem Ahmed


1 Answers

You should check that you are using INNODB as your database type. MyISAM does not support transactions.

like image 187
Jim Avatar answered Nov 01 '22 17:11

Jim