MySQL がデッドロックをバッチで更新する方法を詳しく説明した記事

藏色散人
リリース: 2023-04-13 16:32:37
転載
1600 人が閲覧しました

この記事は、MySQL に関する関連知識を提供します。主に、MySQL がバッチでデッドロックを更新する方法について説明します。コード例もあります。興味のある友人は以下を参照してください。すべての人に役立つことを願っています。 .

MySQL がデッドロックをバッチで更新する方法を詳しく説明した記事

テーブル構造は次のとおりです:

CREATE TABLE `user_item` (
  `id` BIGINT(20) NOT NULL,
  `user_id` BIGINT(20) NOT NULL,
  `item_id` BIGINT(20) NOT NULL,
  `status` TINYINT(4) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_1` (`user_id`,`item_id`,`status`)) ENGINE=INNODB DEFAULT CHARSET=utf-8
ログイン後にコピー

SQL ステートメントは次のとおりです:

update user_item set status=1 where user_id=? and item_id=?
ログイン後にコピー

原因分析:

 mysql的事务支持与存储引擎有关,MyISAM不支持事务,INNODB支持事务,更新时采用的是行级锁。这里采用的是INNODB做存储引擎,意味着会将update语句做为一个事务来处理。前面提到行级锁必须建立在索引的基础,这条更新语句用到了索引idx_1,所以这里肯定会加上行级锁。

 行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。
ログイン後にコピー

この更新ステートメントでは次の手順が実行されます:

  1. 非主キー インデックスが使用されるため、最初に idx_1 の行レベルのロックを取得する必要があります

  2. その後、主キーの更新に従って続行するため、主キーの行レベルのロックを取得する必要があります。

  3. 更新後は、完了したら、すべてのロックを送信して解放します。

ステップ 1 と 2 の間にステートメントが突然挿入された場合: update user_item .....id=? と user_id=? の場合、このステートメントは最初に主キー インデックスをロックします。次に idx_1 をロックします。

厄介な状況が発生します。1 つのステートメントは idx_1 のロックを取得して主キー インデックスのロックを待機し、別のステートメントは主キーのロックを取得して idx_1 のロックを待機します。これにより、デッドロック、ロック。

解決策:

  1. 最初に更新する必要があるレコードの主キー
    select id from user_item where user_id=? and item_id=?
    ログイン後にコピー
    を取得します
  2.  update user_item set status=? where id=? and user_id=?
    ログイン後にコピー
    を 1 つずつ更新します
  3. バッチ サイクルは最初のステップを繰り返します。最初と 2 番目のステップに従うだけです。

推奨される学習: 「MySQL ビデオ チュートリアル

以上がMySQL がデッドロックをバッチで更新する方法を詳しく説明した記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:learnku.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート