Sunday, December 25, 2022

Rollback or Commit with PDO transaction using PHP and MySQL - SELECT query with PDO - PDO with INSERT INTO through prepared statements

A transaction should end with either a rollback() or a commit(), (only one of them). In case you are using MySQL, make sure you are not using MyISAM engine for tables, as it doesn't support transactions. It usually support InnoDB. 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.
<?php
class DB {
    public static function transactional($closure) {
        $dbh = null;
        try {
            $dbh = new PDO("mysql:host=HOST_NAME;dbname=DB_NAME", "DB_USER_NAME", "DB_USER_PASSWORD");

            /*** Set the PDO error mode to exception (will throw exception if any error occurred) ***/
            /*** Follow the link for more info: http://php.net/manual/en/pdo.setattribute.php ***/
            $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $dbh->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_EMPTY_STRING);

            /*** Transaction block starting here ***/
            $dbh->beginTransaction();

            $closure($dbh);

            $dbh->commit();
        }
        catch(Throwable $ex) {
            $dbh->rollback();

            throw $ex;
        }
    }
}

DB::transactional(function (PDO $PDO) {
    $PDO->prepare("INSERT INTO records (`RegistrationID`) VALUES(:RegistrationID)")->execute(['RegistrationID' => 'RegistrationID 1']);
    $PDO->prepare("INSERT INTO records (`RegistrationID`) VALUES(:RegistrationID)")->execute(['RegistrationID' => 'RegistrationID 2']);

    // $PDO->query used to get results
    $result = $PDO->prepare("SELECT * FROM records WHERE `RegistrationID` LIKE :RegistrationID");
    $result->execute(['RegistrationID' => '%RegistrationID%']);
    echo "<pre>";
    print_r($result->fetchAll());
    echo "</pre>";

    Below line will throw an exception and data will not persist into database.
    To persist data into database, comment below line.
    $x = null + null * $PDO->dd();
});
Output be as follows:
Array
(
    [0] => Array
        (
            [id] => 12
            [0] => 12
            [RegistrationID] => RegistrationID 1
            [1] => RegistrationID 1
        )

    [1] => Array
        (
            [id] => 13
            [0] => 13
            [RegistrationID] => RegistrationID 2
            [1] => RegistrationID 2
        )

)

No comments:

Post a Comment