>백엔드 개발 >PHP 튜토리얼 >PHP의 간단한 mysql 잠금 메커니즘 작동에 대한 간략한 분석

PHP의 간단한 mysql 잠금 메커니즘 작동에 대한 간략한 분석

coldplay.xixi
coldplay.xixi앞으로
2021-04-30 17:16:418317검색

PHP의 간단한 mysql 잠금 메커니즘 작동에 대한 간략한 분석

잠금 메커니즘
공유 잠금 및 배타적 잠금
공유 잠금(읽기 잠금): 다른 트랜잭션은 읽을 수 있지만 쓸 수는 없습니다.
배타적 잠금(쓰기 잠금): 다른 트랜잭션은 읽거나 쓸 수 없습니다.

MySQL에는 페이지 레벨, 테이블 레벨, 로우 레벨의 세 가지 잠금 레벨이 있습니다.

  • 페이지 레벨의 대표적인 대표적인 엔진은 BDB입니다.
  • 행 수준의 대표적인 대표적인 엔진은 INNODB입니다.
  • 테이블 레벨의 대표적인 대표적인 엔진으로는 MyISAM, MEMORY, 그리고 오래전의 ISAM이 있습니다.
  • BDB 스토리지 엔진은 페이지 수준 잠금을 사용하지만 테이블 수준 잠금도 지원합니다.
  • InnoDB 스토리지 엔진은 행 수준 잠금(행 수준 잠금)과 테이블 수준 잠금을 모두 지원하지만 기본적으로 행 수준 잠금이 사용됩니다. .
  • MyISAM 및 MEMORY 스토리지 엔진은 테이블 수준 잠금을 사용합니다

관련 무료 학습 권장 사항: php 프로그래밍(비디오)

1 MyISAM 테이블 잠금 모드:

테이블 공유 읽기 잠금(테이블 읽기 잠금): 동일한 테이블에 대한 다른 사용자의 읽기 요청은 차단하지 않지만, 동일한 테이블에 대한 다른 사용자의 쓰기 요청은 차단합니다.

    테이블 독점 쓰기 잠금(테이블 쓰기 잠금) : 동일한 테이블에 대한 다른 사용자의 요청을 차단합니다.
  • MyISAM 테이블 잠금 방법:

MyISAM 테이블을 명시적으로 잠그려면 LOCK TABLES real_table( READ|WRITE), insert_table (READ|WRITE); / /Lock

    UNLOCK TABLES; //Unlock
  • 예:
  • 예를 들어 account(ID, 이름, 현금), Hero(번호)가 있습니다. , 이름, 국가)
테이블 계정 읽기 잠금; 읽기 전용 잠금으로 계정 추가

현재 프로세스 쿼리: 영웅에서 *를 선택하면 테이블 'hero'가 LOCK TABLES로 잠기지 않았다고 보고됩니다.
현재 프로세스는 다른 테이블을 변경합니다. update Hero set name="ss" 여기서 number=1이면 'hero' 테이블이 LOCK TABLES로 잠기지 않았다고 보고됩니다.

현재 프로세스는 테이블을 변경합니다. update account set name="ssss" 여기서 id=1 ; 테이블 '계정'이 READ 잠금으로 잠겨 업데이트할 수 없다고 보고합니다.
    다른 mysql 프로세스가 들어오면 다른 테이블과 계정을 쿼리할 수 있지만 계정을 변경할 수는 없습니다. 실행하기 전에 잠금을 해제해야 합니다



  1. 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는 추가하지 않습니다.
잠금은 트랜잭션 실행 중에만 사용할 수 있습니다.

잠금은 커밋 실행 중에만 사용할 수 있습니다. 또는 롤백할 때 해제되며 모든 잠금이 동시에 해제됩니다.

공유 잠금: SELECT * FROM table_name WHERE … 공유 모드에서 잠금. 다른 세션에서는 여전히 레코드를 쿼리하고 공유 모드 공유 잠금을 레코드에 추가할 수 있습니다. 그러나 현재 트랜잭션이 레코드를 업데이트해야 하는 경우 교착 상태가 발생할 가능성이 높습니다. 누구나 읽을 수 있지만 변경할 수는 없습니다. 배타적 공유 잠금 중 하나가 잠겨 있는 경우에만 변경할 수 있습니다.
배타적 잠금(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: 기다리지 않고 대기 중인 잠금을 찾은 후 즉시 오류가 반환됩니다. 잠금 시간이 초과됩니다.
  • –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 >

SHOW PROCESSLIST는 실행 중인 스레드를 보여줍니다.

위 내용은 PHP의 간단한 mysql 잠금 메커니즘 작동에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제