8

私はPDOについてのこのチュートリアルを通過し、トランザクションについてのポイントに到達しました。接続部分をスキップして、私はこのphpコードを持っています:

try
{
    $db->beginTransaction();

    $db->exec('DROP TABLE IF EXISTS animals');

    $db->exec('CREATE TABLE animals ('
        .'animal_id MEDIUMINT(8) NOT NULL AUTO_INCREMENT PRIMARY KEY,'
        .'animal_type VARCHAR(25) NOT NULL,'
        .'animal_name VARCHAR(25) NOT NULL)'
        .'ENGINE=INNODB');

    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("emu", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("funnel web", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("lizard", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("dingo", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("kangaroo", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("wallaby", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("wombat", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("koala", "bruce")');
    $db->exec('INSERT INTO animals (animal_type, animal_name) VALUES ("kiwi", "bruce")');

    $db->commit();

    echo 'Table re-created and data entered successfully.';
}
catch(PDOException $e)
{
    $db->rollback();

    echo $e->getMessage();
}

どこかでエラーを入れた場合を除いて、それはうまく動作し、私が思ったように動作します。4番目の挿入ステートメントで間違いを犯した場合のように、データベースに3匹の動物が見つかります。しかし、ロールバックされるはずだと思っていました。つまり、このスクリプトを実行する前と同じようにデータベースを見つけることができました。

私は何かを誤解しましたか?私は何が欠けていますか?トランザクション関数とロールバック関数は、私が思っていること以外のことをしますか?ドロップアンドクリエイトステートメントは、トランザクションを何らかの形で「中断」していますか?何が起きてる?


更新:テーブルが作成された後にのみトランザクションが開始されるように行を移動すると、期待した動作が得られます。$db->beginTransaction();したがって、3番目の挿入ステートメントが失敗した場合、トランザクションがロールバックされた後、(再作成されたばかりなので)空のテーブルが作成されます。ドロップステートメントとクリエイトステートメントがトランザクション内にあるのに、なぜそれが機能しないのか疑問に思っています...

4

2 に答える 2

19

PHPリファレンスマニュアルを確認してください:PDO :: beginTransaction

MySQLを含む一部のデータベースは、DROPTABLEやCREATETABLEなどのデータベース定義言語(DDL)ステートメントがトランザクション内で発行されると、暗黙のCOMMITを自動的に発行します。暗黙のCOMMITは、トランザクション境界内の他の変更をロールバックすることを防ぎます。

これは、これが発生する理由を説明しています。これは、PDO / PHPではなく、MySQLの制限です。

于 2010-03-11T16:03:56.450 に答える
2

すべてのテーブルがトランザクションをサポートしていることを確認してください。たとえば、MyISAMはサポートしていません。

于 2012-08-18T01:27:26.163 に答える