データベースから古いデータを削除し、別のデータベースからデータを読み込み、最初に新しいデータを挿入するPHPスクリプトがあります。明らかな理由から、トランザクションを使用して、可能なすべてのエラーをロールバックして、これを使用したかったのです。これは、予期せぬ1ビットのことを除いてはうまくいくと思われます。"コミット"せずに実行されているMySqlトランザクションの一部
(意図的に)スクリプトを中断すると、すべてのDELETEステートメントは、とにかく実行されたと思われるものを除いて、正常にロールバックされます。
コードは、その他の詳細のうちの「タスク」のアレイ、各アレイ、テーブル名、データの種類の人間が読める記述、及びソース・データベースの特定のSELECT文を有します。ここではその「ワークリスト」配列のフラグメントです:
$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 ... "
)
);
は、この「ワークリスト」を定義した後、以下のように、私は自分のトランザクションを開始します。
$dbfront = new PDO(...);
$dbfront->exec("SET AUTOCOMMIT = 0");
$dbfront->beginTransaction();
$dbfront->exec("SET FOREIGN_KEY_CHECKS=0");
ワークリスト通じたIループの後のように、古いデータを削除します次の:
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;
}
}
はその後、他のデータベースから新しいデータを選択すると「dbfront」に挿入するコードがあります、そして最後に、私は、変更をコミットするために、この部分を持っている:
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;
}
誰もが、私はこのスクリプトを途中で中断したときに完全にロールバックされた最初の二つのテーブルのためのもっともらしい説明、およびどんな実行されないことにする第三いずれかであるかもしれないものの任意のアイデアを持っていますか?
トランザクションのコミットされた部分は、おそらくInnoDB以外のテーブルで動作しますか? –
は正直に言うと、この種のものは、私がDarhazerで行くと思いストアドプロシージャ... – gbn
に適し(アトミックです削除の特にSAシリーズ)です。 mysqlクライアントでSHOW TABLE STATUSを試して、InnoDB以外のテーブルを探し、それらがトランザクションであることを確認してください。 – Jaydee