PHP の mysql ロック メカニズムの簡単な操作の簡単な分析

coldplay.xixi
リリース: 2023-04-09 22:42:01
転載
8299 人が閲覧しました

PHP の mysql ロック メカニズムの簡単な操作の簡単な分析

ロック機構
共有ロックと排他ロック
共有ロック (読み取りロック): 他のトランザクションは読み取りはできますが、書き込みはできません。
排他的ロック (書き込みロック): 他のトランザクションは読み書きできません。

MySQL には、ページ レベル、テーブル レベル、行レベルの 3 つのロック レベルがあります。

  • ページ レベルの代表的なエンジンは BDB です。
  • 行レベルの代表的なエンジンは INNODB です。
  • テーブルレベルの代表的なエンジンとしては、MyISAM、MEMORY、そして一昔前のISAMなどが挙げられます。
  • BDB ストレージ エンジンはページ レベルのロックを使用しますが、テーブル レベルのロックもサポートします
  • InnoDB ストレージ エンジンは行レベルのロック (行レベルのロック) とテーブル レベルのロックの両方をサポートします。 -レベルのロックですが、デフォルトでは行レベルのロックが使用されます。
  • MyISAM および MEMORY ストレージ エンジンはテーブル レベルのロックを使用します

関連する無料学習の推奨事項: php プログラミング (ビデオ)

1. MyISAM テーブル ロック

MyISAM テーブル レベル ロック モード:

  • テーブル共有読み取りロック (テーブル読み取りロック): いいえ同じテーブルに対する他のユーザーの読み取りリクエストはブロックされますが、同じテーブルに対する他のユーザーの書き込みリクエストはブロックされます。
  • テーブル排他的書き込みロック (テーブル書き込みロック): 他のユーザーの読み取りおよび書き込み操作をブロックします。同じテーブル上;

MyISAM テーブルのロック方法:

  • LOCK TABLE コマンドを使用して、MyISAM テーブルを明示的にロックします
  • LOCK TABLES real_table (READ |WRITE), insert_table (READ|WRITE); //Lock
  • UNLOCK TABLES; //Unlock

例:
たとえば、 is account(id,name,cash), hero (number, name, country) これら 2 つのテーブル

  1. ロック テーブル アカウントの読み取り; アカウントを読み取り専用ロックとして追加します
    現在のプロセス クエリ: select * from hero; will レポート テーブル 'hero' が LOCK TABLES でロックされていませんでした。
    現在のプロセスは他のテーブルを変更します: update hero set name="ss" wherenumber=1; will report Table 'hero' was not locked with LOCK TABLES
    現在のプロセスはテーブルを変更します: update account set name= "ssss" where id=1; テーブル 'account' が READ ロックでロックされており、更新できないことが報告されます
    別の mysql プロセスが入ってきた場合、他のテーブルやアカウントをクエリすることはできますが、変更することはできませんロックが実行される

1.1PHP操作

<?php/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2021/4/29 0029
 * Time: 11:20
 */$link = new mysqli(&#39;127.0.0.1&#39;, &#39;root&#39;, &#39;123&#39;, &#39;db_school&#39;); // 连接数据库if(mysqli_connect_errno()){                                // 检查连接错误
    printf("连接失败:%s<br>", mysqli_connect_error());
    exit();}//(s1)$table = "account";$type = "read";$sql1 = "LOCK TABLES $table $type";$link->query($sql1);//处理逻辑//$sql1 = "select * from $table;";        //(s1)true//$sql1 = "select * from hero;";        //false//$sql1 = "update hero set name='ss' where number=1; ";     //false$sql1 = "update account set name='ssss' where id=1;";   //false$result = $link->query($sql1);var_dump($result);sleep(20);  //测试    //假设还没释放锁,开启cmd进mysql(s2)可以查询,但不能执行更改和删除操作,会等待这边释放锁$link->query("unlock tables");    //取消全部的锁//解锁后正常操作//$result = $link -> query($sql1);//var_dump($result);$link->close();
ログイン後にコピー

クエリテーブルレベルのロック競合
'Table%' のようなステータスを表示;

  • Table_locks_immediate は、テーブル レベルのロックをすぐに取得できる回数を指します。
  • Table_locks_waited は、テーブル レベルのロックをすぐに取得できる回数を指します。レベル ロックはすぐには取得できないため、待つ必要があります。

2. InnoDB ロック メソッド:

通常の SELECT ステートメントの場合、InnoDB はロックを追加しません。 ##ロックはトランザクション実行中のみ使用できます ロックはトランザクション実行中のみ使用できます。コミットまたはロールバックが実行された場合にのみ解放され、すべてのロックが同時に解放されます。

    共有ロック(S): SELECT * FROM table_name WHERE ... 共有モードでロックします。他のセッションは引き続きレコードをクエリし、共有モードの共有ロックをレコードに追加できます。ただし、現在のトランザクションでレコードを更新する必要がある場合は、デッドロックが発生する可能性があります。誰でも読み取ることができますが、変更することはできません。排他的共有ロックの 1 つがロックされている場合にのみ変更できます;
  • 排他的ロック (X): SELECT * FROM table_name WHERE ... FOR UPDATE。他のセッションはレコードをクエリできますが、レコードに共有ロックや排他ロックを追加することはできず、ロックの取得を待ちます。変更したいのですが、変更できず、読み取ることもできません
  • #select … 共有モードでロック //共有ロック
    #select … 更新用 //排他ロック
    ##MySQL 8.0 の場合
    共有ロック (S): SELECT * FROM table_name WHERE … FOR SHARE
  • 排他ロック (X): SELECT * FROM table_name WHERE … FOR UPDATE[NOWAIT|SKIP LOCKED] ]
  • –NOWAIT: Discovery ロックを待った後、すぐにエラーが返されるため、ロックのタイムアウトを待ってエラーを報告する必要はありません。
  • –SKIP LOCKED: ロックされた行をスキップし、他の行を直接更新しますが、更新結果が期待を満たさないかどうかに注意してください。

2.1PHP 操作
<?php/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2021/4/29 0029
 * Time: 10:06
 */$link = new mysqli(&#39;127.0.0.1&#39;, &#39;root&#39;, &#39;123&#39;, &#39;db_school&#39;); // 连接数据库if(mysqli_connect_errno()){                                // 检查连接错误
    printf("连接失败:%s<br>", mysqli_connect_error());
    exit();}//案例1$id = 1; //明确指定主键,并且有此数据,row lock (行锁)//$id = -1;   //明确指定主键,若查无此数据,无lock (无锁)$link->autocommit(0);                   // 开始事务(s1)//FOR UPDATE仅适用于InnoDB,且必须在交易区块(BEGIN/COMMIT)中才能生效。$sql = "select * from account where id=$id for update";$link->query($sql);/***
 * 此时其他mysql进程可以查询该记录,但是不能对该记录加共享锁或排他锁,而是等待获得锁。
 *///(s1)可以进行更改,和查询等操作//$sql1 = "update account set name='aaa' where id=$id;";  //进行更改//$sql1 = "select * from account where id=$id;";  //进行查询$sql1 = "delete from account where id=$id;";  //进行删除$result = $link -> query($sql1);var_dump($result);sleep(20); //测试    //假设还在事务处理中,开启cmd进mysql(s2)执行更改和删除操作,会等待这边释放锁$link->commit();$link->close();
ログイン後にコピー

ロックされているテーブルを表示
show OPEN TABLES where In_use > 0;

SHOW PROCESSLIST どのスレッドを表示走っている。

以上がPHP の mysql ロック メカニズムの簡単な操作の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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