I'm about to implement transactions in my php scripts and I'm doing some testing to help myself understand exactly how they work. I have the following code snippet:
try{
$db->beginTransaction();
$update = "UPDATE persons SET first_name = 'Adam' WHERE person_id = 4";
$stmt = $db->exec($update);
$select = "SELECT person_id, column_that_doesnt_exist FROM persons";
try{
$stmt = $db->prepare($select);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode('success');
} catch (PDOException $e) {
echo 'execute failure';
}
echo ' code gets here';
$db->commit();
} catch(PDOException $e){
$db->rollBack();
echo json_encode('commit failure');
}
which outputs:
execute failure code gets here
And person 4's first name is updated to Adam.
Now I'm pretty sure that it's getting committed because the second query never actually failed, because it was never actually executed since the prepare
was the point of failure.
It would be nice if a PDOException
was thrown for the last catch
since one was thrown in the "inner" try
but I can work around that.
Now if I take out the "inner" try
and have this code:
try{
$db->beginTransaction();
$update = "UPDATE persons SET first_name = 'Adam' WHERE person_id = 4";
$stmt = $db->exec($update);
$select = "SELECT person_id, column_that_doesnt_exist FROM persons";
$stmt = $db->prepare($select);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$db->commit();
} catch(PDOException $e){
$db->rollBack();
echo json_encode('commit failure');
}
the commit fails, db is rolled back and outputs commit failure
as expected.
So in production, should I NOT wrap each individual statement in a try-catch
, and instead throw all of my statements inside one big try
block (transaction), then catch the commit
Exception at the end? This doesn't seem right to me....and likewise wouldn't give you much info about which statement failed....