잠금 메커니즘
공유 잠금 및 배타적 잠금
공유 잠금(읽기 잠금): 다른 트랜잭션은 읽을 수 있지만 쓸 수는 없습니다.
배타적 잠금(쓰기 잠금): 다른 트랜잭션은 읽거나 쓸 수 없습니다.
MySQL에는 페이지 레벨, 테이블 레벨, 로우 레벨의 세 가지 잠금 레벨이 있습니다.
- 페이지 레벨의 대표적인 대표적인 엔진은 BDB입니다.
- 행 수준의 대표적인 대표적인 엔진은 INNODB입니다.
- 테이블 레벨의 대표적인 대표적인 엔진으로는 MyISAM, MEMORY, 그리고 오래전의 ISAM이 있습니다.
- BDB 스토리지 엔진은 페이지 수준 잠금을 사용하지만 테이블 수준 잠금도 지원합니다.
- InnoDB 스토리지 엔진은 행 수준 잠금(행 수준 잠금)과 테이블 수준 잠금을 모두 지원하지만 기본적으로 행 수준 잠금이 사용됩니다. .
- MyISAM 및 MEMORY 스토리지 엔진은 테이블 수준 잠금을 사용합니다
관련 무료 학습 권장 사항: php 프로그래밍(비디오)
테이블 공유 읽기 잠금(테이블 읽기 잠금): 동일한 테이블에 대한 다른 사용자의 읽기 요청은 차단하지 않지만, 동일한 테이블에 대한 다른 사용자의 쓰기 요청은 차단합니다.
테이블 독점 쓰기 잠금(테이블 쓰기 잠금) : 동일한 테이블에 대한 다른 사용자의 요청을 차단합니다.
- MyISAM 테이블 잠금 방법:
MyISAM 테이블을 명시적으로 잠그려면 LOCK TABLES real_table( READ|WRITE), insert_table (READ|WRITE); / /Lock
UNLOCK TABLES; //Unlock
- 예:
예를 들어 account(ID, 이름, 현금), Hero(번호)가 있습니다. , 이름, 국가)
테이블 계정 읽기 잠금; 읽기 전용 잠금으로 계정 추가'Table%'와 같은 상태 표시;현재 프로세스 쿼리: 영웅에서 *를 선택하면 테이블 'hero'가 LOCK TABLES로 잠기지 않았다고 보고됩니다.
현재 프로세스는 테이블을 변경합니다. update account set name="ssss" 여기서 id=1 ; 테이블 '계정'이 READ 잠금으로 잠겨 업데이트할 수 없다고 보고합니다.
현재 프로세스는 다른 테이블을 변경합니다. update Hero set name="ss" 여기서 number=1이면 'hero' 테이블이 LOCK TABLES로 잠기지 않았다고 보고됩니다.다른 mysql 프로세스가 들어오면 다른 테이블과 계정을 쿼리할 수 있지만 계정을 변경할 수는 없습니다. 실행하기 전에 잠금을 해제해야 합니다
테이블 수준 잠금 경합 쿼리
1.1PHP 작업<?php/** * Created by PhpStorm. * User: Administrator * Date: 2021/4/29 0029 * Time: 11:20 */$link = new mysqli('127.0.0.1', 'root', '123', 'db_school'); // 连接数据库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_locks_immediate는 테이블 수준 잠금이 가능한 횟수를 나타냅니다. 즉시 얻을 수 있습니다잠금은 트랜잭션 실행 중에만 사용할 수 있습니다. 잠금은 커밋 실행 중에만 사용할 수 있습니다. 또는 롤백할 때 해제되며 모든 잠금이 동시에 해제됩니다.
Table_locks_waited는 즉시 얻을 수 없는 테이블 수준 잠금을 나타냅니다. 잠금을 기다려야 하는 횟수일반적인 SELECT 문의 경우 InnoDB는 추가하지 않습니다.
- 2. InnoDB 잠금 방법:
Show OPEN TABLES where In_use >공유 잠금: SELECT * FROM table_name WHERE … 공유 모드에서 잠금. 다른 세션에서는 여전히 레코드를 쿼리하고 공유 모드 공유 잠금을 레코드에 추가할 수 있습니다. 그러나 현재 트랜잭션이 레코드를 업데이트해야 하는 경우 교착 상태가 발생할 가능성이 높습니다. 누구나 읽을 수 있지만 변경할 수는 없습니다. 배타적 공유 잠금 중 하나가 잠겨 있는 경우에만 변경할 수 있습니다.
#select ... 공유 모드에서 잠금 //공유 잠금
배타적 잠금(X): SELECT * FROM table_name WHERE ... FOR UPDATE. 다른 세션은 레코드를 쿼리할 수 있지만 공유 잠금이나 배타적 잠금을 레코드에 추가할 수는 없지만 잠금을 얻을 때까지 기다립니다. 변경하고 싶은데 변경할 수도 읽을 수도 없습니다#select ... 업데이트용 //독점 잠금
잠긴 테이블 보기- ##MySQL 8.0
- 공유 잠금(S ): SELECT * FROM table_name WHERE … FOR SHARE
–SKIP LOCKED: 잠긴 행을 건너뛰고 다른 행을 직접 업데이트하지만 업데이트 결과가 기대에 미치지 못할지 주의하세요.
독점 잠금(X): SELECT * FROM table_name WHERE … FOR UPDATE[NOWAIT|SKIP LOCKED]
–NOWAIT: 기다리지 않고 대기 중인 잠금을 찾은 후 즉시 오류가 반환됩니다. 잠금 시간이 초과됩니다.
2.1PHP 작업<?php/** * Created by PhpStorm. * User: Administrator * Date: 2021/4/29 0029 * Time: 10:06 */$link = new mysqli('127.0.0.1', 'root', '123', 'db_school'); // 连接数据库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();
위 내용은 PHP의 간단한 mysql 잠금 메커니즘 작동에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!