ホームページ  >  記事  >  データベース  >  MySQL 行レベルのロックとデッドロック防止ソリューションの使用

MySQL 行レベルのロックとデッドロック防止ソリューションの使用

黄舟
黄舟オリジナル
2017-01-18 11:59:291503ブラウズ

Mysql リレーショナル データベース管理システム

MySQL は、スウェーデンの MySQL AB 社によって開発された、オープンソースの小規模リレーショナル データベース管理システムです。 MySQL は、インターネット上の小規模および中規模の Web サイトで広く使用されています。 MySQL は、サイズが小さく、速度が速く、総所有コストが低く、特にオープンソースの特性により、Web サイトの総所有コストを削減するために、多くの中小規模の Web サイトが Web サイト データベースとして MySQL を選択しています。


MySQL の InnoDB はトランザクションと行レベルのロックをサポートしており、行ロックはユーザーの引き出しやその他のサービスの処理に使用できます。 mysql ロックを使用するとデッドロックが発生することがあります。デッドロックを防止します。この記事では、実践的なアプリケーションを通じて説明します

1. はじめに

MySQL の InnoDB はトランザクションと行レベルのロックをサポートしており、行ロックはユーザーの引き出しやその他のサービスの処理に使用できます。 mysql ロックを使用するとデッドロックが発生することがあります。デッドロックを防止します。

2. MySQL の行レベルのロック

行レベルのロックは共有ロックと排他ロックに分けられます。

共有ロック:

」 共有ロックは、読み取りロックとも呼ばれます。共有ロックを追加した後、すべてのトランザクションは読み取り操作のみを実行できますが、他のトランザクションは排他ロックを追加できず、行を追加することしかできません。 -レベルのロック。

使用法:

SELECT `id` FROM table WHERE id in(1,2)  LOCK IN SHARE MODE

結果セット内のデータは共有ロックになります

排他的ロック:

名詞の説明: 何かが行に排他的ロックを追加した場合、このトランザクションのみがそのロックを読み書きでき、他のトランザクションはいいえ他のプロセスはそれを読み取ることができますが、書き込み操作を実行できないため、その解放を待つ必要があります。

使い方:

SELECT `id` FROM mk_user WHERE id=1 FOR UPDATE

3. アプリケーション例

<?php
  $uid=$_SESSION[&#39;uid&#39;];
  //开启事务
  sql:begin
  //开启行级锁的排他锁
  sql:SELECT `coin` FROM user WHERE id=$uid FOR UPDATE 
  //扣除用户账户钱币
  $res=update user set coin=coin-value where id=1;
  if($res){
   //将用户的提现信息添加到提现表
   sql:insert into user values(null,"{$uid}",value);
   //判断添加结果
   if(add_cash_result){
    sql:commit
   }else{
    sql:rollback
   }
  }else{
   sql:rollback;
  }

実際、手順は複雑ではなく、トランザクションを開始してそれぞれの結果が true かどうかを判断し、false であれば送信してロールバックするだけです。単一の排他ロックでは問題ありません。テーブルに複数の排他ロックが関連付けられている場合は、デッドロックを防ぐために注意する必要があります。

4. デッドロック

`id` 主キーインデックス

`name` インデックスインデックス

`age` 通常フィールド

デッドロックの根本的な原因は、2 つ以上のプロセスが互いにリソースを解放する必要があるため、プロセスはすべて待たされました。コードでは、2 つ以上のトランザクションがもう一方のトランザクションでリソースを解放する必要があるためです。

デッドロックの必要条件は、相互排他条件、ループ条件、リクエスト保持、無資格の4つであり、それぞれの条件が崩れていればデッドロックは発生しない。

例えば、次の 2 つのステートメントの最初のステートメントは、name が主キー インデックスではないため、最初に `name` インデックスを使用し、主キー インデックスも使用されます

2 番目のステートメントは、最初に主キー インデックスを使用します2 つのステートメントが同時に実行され、2 番目のステートメントが主キー インデックスを解放するのを待ちます。インデックスを作成し、最初の名前のインデックスを待ちます。これによりデッドロックが発生します。

解決策: 主キーの値に基づいて更新されるように最初のステートメントを変換します

#①
update mk_user set name =&#39;1&#39; where `name`=&#39;idis12&#39;;
#②
update mk_user set name=&#39;12&#39; where id=12;
//改造后
update mk_user set name=&#39;1&#39; where id=(select id from mk_user where name=&#39;idis12&#39; );

上記は、Mysql の行レベルのロックとデッドロック防止ソリューションの使用に関する内容です。さらに関連する内容については、 に注目してください。 PHP 中国語 Web サイト (www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。