This is a short tutorial on how to use transactions with PDO object in PHP. For those who don’t know; database transactions represent a “block” or “unit” of work. In most cases, this “unit” of work will consist of multiple queries that are somehow related to one another. In certain scenarios, you might want to ensure that all queries have executed successfully BEFORE you commit the changes to the database. Example: The second query should not be executed if the first query fails.
For this example, I’m going to create a mock application that adds credit or money to a user’s account:
* Connect to MySQL and instantiate the PDO object.
* Set the error mode to throw exceptions and disable emulated prepared statements.
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '', array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false
//We are going to assume that the user with ID #1 has paid 10.50.
$userId = 1;
$paymentAmount = 10.50;
//We will need to wrap our queries inside a TRY / CATCH block.
//That way, we can rollback the transaction if a query fails and a PDO exception occurs.
//We start our transaction.
//Query 1: Attempt to insert the payment record into our database.
$sql = "INSERT INTO payments (user_id, amount) VALUES (?, ?)";
$stmt = $pdo->prepare($sql);
//Query 2: Attempt to update the user's profile.
$sql = "UPDATE users SET credit = credit + ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
//We've got this far without an exception, so commit the changes.
//Our catch block will handle any exceptions that are thrown.
//An exception has occured, which means that one of our database queries
//Print out the error message.
//Rollback the transaction.
A run-down of the PHP above:
- We connected to MySQL using the PDO object. We set the error mode to PDO::ERRMODE_EXCEPTION so that failed queries will result in a PDO Exception being thrown. We also disabled emulated prepared statements by setting PDO::ATTR_EMULATE_PREPARES to false.
- For example purposes, I’ve set the User ID to 1 and the payment amount to 10.50.
- We begin our transaction by calling the beginTransaction function. As soon as this function is called, the autocommit mode for MySQL is set to 0 (by default, this is set to 1).
- We open our Try / Catch block. We will run all of our queries inside the Try block so that we can catch any exceptions that occur.
- We insert the payment into our payments table.
- We then update the user’s account with his / her new credit count.
- Finally, we commit the transaction by calling the commit function.
If one of our queries fail, a PDO exception will be thrown and the code inside our catch block will be executed. This means that the entire transaction will be rolled back if an error occurs.
Explanation of transaction terms.
A quick explanation of some of the key terms:
- Begin transaction: The transaction is started and the default autocommit nature of MySQL is disabled. Example: If you run an INSERT query, the data won’t be inserted straight away.
- Commit: When you commit a transaction, you are basically telling MySQL that everything went OK and that the results of your queries are to be made final.
- Rollback: When you rollback a transaction, you are basically telling MySQL that you do not want the changes to be committed. This is often used whenever a query fails.