sql >> データベース >  >> RDS >> Mysql

mysqli::commitとmysqli::rollbackはどのように機能しますか?

    いいえ、単一のSQLステートメントが失敗した場合、トランザクションは追跡しません。

    単一のSQLステートメントがステートメントに失敗した場合 ロールバックされます(@eggyalの回答で説明されているように)-ただし、トランザクション まだ開いています。 commitを呼び出す場合 現在、成功したステートメントのロールバックはなく、「破損した」データをデータベースに挿入しただけです。これは簡単に再現できます:

    m> CREATE TABLE transtest (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
     name VARCHAR(100) NOT NULL DEFAULT '',
     CONSTRAINT UNIQUE KEY `uq_transtest_name` (name)) ENGINE=InnoDB;
    Query OK, 0 rows affected (0.07 sec)
    
    m> START TRANSACTION;
    Query OK, 0 rows affected (0.00 sec)
    
    m> INSERT INTO transtest (name) VALUE ('foo');
    Query OK, 1 row affected (0.00 sec)
    
    m> INSERT INTO transtest (name) VALUE ('foo');
    ERROR 1062 (23000): Duplicate entry 'foo' for key 'uq_transtest_name'
    
    m> INSERT INTO transtest (name) VALUE ('bar');
    Query OK, 1 row affected (0.00 sec)
    
    m> COMMIT;
    Query OK, 0 rows affected (0.02 sec)
    
    m> SELECT * FROM transtest;
    +----+------+
    | id | name |
    +----+------+
    |  3 | bar  |
    |  1 | foo  |
    +----+------+
    2 rows in set (0.00 sec)
    

    2番目のSQLステートメントが失敗したにもかかわらず、「foo」と「bar」の挿入が成功したことがわかります。AUTO_INCREMENTも確認できます。 -クエリの誤りにより値が増加しました。

    したがって、各queryの結果を確認する必要があります -呼び出し、失敗した場合はrollbackを呼び出します それ以外の場合は成功したクエリを元に戻します。したがって、PHPマニュアルのLorenzoのコードは理にかなっています。

    MySQLにトランザクションのロールバックを強制する唯一のエラーは「トランザクションデッドロック」です(これはInnoDBに固有であり、他のストレージエンジンはこれらのエラーを異なる方法で処理する場合があります)。



    1. mysqlテーブルのインデックスを再作成する方法

    2. mysqlクエリで親ごとにすべての子を取得します

    3. mysqldatetimeをphpdatetimeに変更します-ローカルはstrtotime()によって機能しません

    4. SQL Server(T-SQL)から電子メールでクエリ結果を送信するときにパディングを削除する