1. ホーム
  2. マイスル

mysqlのデッドロックエラーを解決する SQLSTATE[HY000]: 一般的なエラーです。1205 ロック待ちタイムアウトを超えました。

2022-02-27 02:55:06

sqlstate[hy000]: 一般的なエラーです。1205 ロック待ちのタイムアウトを超えましたので、トランザクションを再スタートしてください。

PHP のデバッグ中に、例外をコミットした後にトランザクションをロールバックしなかったため、mysql がデッドロックになり、その後のリクエストでデータを更新できなくなりました。

問題の原因

   トランザクションはコミットされず、ロールバックもされないまま、トランザクションBが実行され、同じデータが変更されます。

このとき、トランザクションBはタイムアウトするまでaがロックを解放するのを待ち、設定されたタイムアウト時間後にエラーが発生する

本問題は以下の環境で発生します。


1. 同一トランザクション内で、同じデータに対して連続して挿入と更新の操作を行うこと。 
2. 同じデータベース上で複数のサーバーが動作すること。 
3. 瞬時に発生する高い並行性。

4、ステートメントがコミットを実行せず、returnが終了する前にロールバックも行わなかった。

例えば、パラメータチェックが通らない場合、エラーメッセージが直接返され、結果的にロールバックが実行できなくなります

このような次のコードは、最初に更新操作を実行し、エラーとリターンが直接、無ロールバックの結果、この操作は、ロールバック前に少しを返すために、または例外を投げる統一パウンス後にエラーメッセージを返します。

$this->startTrans();
        try {
           
            
            $user = new User();
            $user->where('id',$userId)->update(['realname'=>$parentName]);
           
                $existId = $this->where('class_id',$classId)->where('student_number',$number)->find();
                if ($existId)
                    return ['data' => '', 'code' => 300, 'msg' => 'student_number_duplicate'];
            $this-> commit();
       
        } catch (Throwable $e) {
            $this-> rollback();
            return ['data' => '', 'code' => 20102, 'msg' => $e-> getMessage()];
        }


例外メッセージ 

SQLSTATE[HY000]: 一般的なエラーです。1205 ロック待ちのタイムアウトを超えました。

解決方法

1. 以下のステートメントでコミットトランザクションのデータを探し、スレッドを強制終了する。

select * from information_schema.innodb_trx


<イグ

trx_mysql_thread_idは、プロセス

kill 1544

関連する除外文

完全なプロセスリストを表示する ## 現在接続されているスレッド

select * from information_schema.innodb_trx ## 現在実行中のすべてのトランザクション 

select * from information_schema.innodb_locks ## 現在存在するロック 

select * from information_schema.innodb_lock_waits ## ロック待ちの対応表

フィールドの詳細

desc information_schema.innodb_locks;

フィールドタイプ Null Key Default Remark
lock_id varchar(81) NO ロックID
lock_trx_id varchar(18) NO ロックを所有するトランザクションのID
lock_mode varchar(32) NO ロックモード
lock_type varchar(32) NO ロックタイプ
lock_table varchar(1024) NO ロックされるテーブル
lock_index varchar(1024) YES NULL ロックされているインデックスを指定します。
lock_space bigint(21) unsigned YES NULL ロックされた表領域の番号です。
lock_page bigint(21) unsigned YES NULL ロックされたページの番号
lock_rec bigint(21) unsigned YES NULL ロックされるレコード番号
lock_data varchar(8192) YES NULL ロックされるデータ
desc 情報_schema.innodb_lock_waits

フィールドタイプ Null Key Default Remark
request_trx_id varchar(18) NO 要求されたロックのトランザクション ID
requested_lock_id varchar(81) NO 要求されたロックのロック ID
blocking_trx_id varchar(18) NO 現在所有しているロックのトランザクションID
blocking_lock_id varchar(81) NO 現在所有しているロックのID
desc information_schema.innodb_trx ;

フィールドタイプ Null Key デフォルト Extra Remark
trx_id varchar(18) NO トランザクションID
trx_state varchar(13) NO トランザクションの状態。
trx_started datetime NO 0000-00-00 00:00:00 トランザクションの開始時間です。
trx_requested_lock_id varchar(81) YES NULL innodb_locks.lock_id
trx_wait_started datetime YES NULL トランザクションが待機を開始した時間です。
trx_weight bigint(21) unsigned NO 0 #.
trx_mysql_thread_id bigint(21) unsigned NO 0 トランザクションスレッドID
trx_query varchar(1024) YES NULL 特定のSQL文
trx_operation_state varchar(64) YES NULL トランザクションの現在の操作状態です。
trx_tables_in_use bigint(21) unsigned NO 0 トランザクションで使用されているテーブルの数
trx_tables_locked bigint(21) unsigned NO 0 トランザクションが持っているロックの数
trx_lock_structs bigint(21) unsigned NO 0 #.
trx_lock_memory_bytes bigint(21) unsigned NO 0 トランザクションによってロックされたメモリのサイズ(B)。
trx_rows_locked bigint(21) unsigned NO 0 トランザクションによってロックされた行の数
trx_rows_modified bigint(21) unsigned NO 0 トランザクションによって変更された行の数。
trx_concurrency_tickets bigint(21) unsigned NO 0 トランザクションの同時実行チケットの数
trx_isolation_level varchar(16) NO トランザクションの分離レベル
trx_unique_checks int(1) NO 0 一意性チェックの有無
trx_foreign_key_checks int(1) NO 0 外部キーチェックを行うかどうか
trx_last_foreign_key_error varchar(256) YES NULL 直近の外部キーエラー
trx_adaptive_hash_latched int(1) NO 0 #.
trx_adaptive_hash_timeout bigint(21) unsigned NO 0 #3