Reputation: 67
I've got a PHP script that deletes old data from a database, reads data from another, then inserts the new data in the first. For obvious reasons, I wanted to this using transactions, with a rollback on every possible error. This seems to work, except for one bit of unexpected and - to me - unexplicable behaviour.
When (purposefully) interrupting the script, all of my DELETE statements are succesfully rolled back except one that seems to have been executed anyway.
The code has an array of 'tasks', each an array with, among other details, a table name, a human-readable description of the kind of data, and the specific SELECT statement for the source database. Here's a fragment of that 'worklist' array:
$worklist = array(
array(
"table" => "campaign",
"description" => "campaign details",
"selectsql" => "SELECT ... "
),
array(
"table" => "product",
"description" => "product",
"selectsql" => "SELECT ... "
),
...
array(
"table" => "context_search",
"description" => "product details for search",
"selectsql" => "SELECT ... "
)
);
After defining this 'worklist', I start my transaction as follows:
$dbfront = new PDO(...);
$dbfront->exec("SET AUTOCOMMIT = 0");
$dbfront->beginTransaction();
$dbfront->exec("SET FOREIGN_KEY_CHECKS=0");
After which I loop through the worklist to delete old data as follows:
foreach($worklist as $job){
$deleter = $dbfront->prepare("DELETE FROM "
. $job["table"] .
" WHERE
campaign_id = " . $campaign_id .
";");
try{
$deleter->execute();
echo $deleter->rowCount() . "lines of old data deleted from " . $job["table"] . " table\n";
} catch (exception $e){
echo $e . "\n";
$dbfront->rollBack();
echo "An error occurred. All changes have been rolled back.\n";
exit;
}
}
Then, there's the code to select new data from the other database and to insert it into 'dbfront', and then at the end, I have this part to commit the changes:
try {
$dbfront->commit();
echo "\nAll changes committed\n";
} catch (Exception $e) {
echo $e . "\n";
$dbfront->rollBack();
echo "An error occurred. All changes have been rolled back.\n";
exit;
}
Does anyone have any idea what might be a plausible explanation for the first two tables to be rolled back perfectly when I interrupt this script halfway, and the third one to be executed no matter what?
Upvotes: 1
Views: 711
Reputation: 26709
Not all storage engines in MySQL support transactions. If transaction operates on MyISAM table, the changes in that table will be commited regardless if the rest of transaction is commited or rollbacked.
Upvotes: 3