>  기사  >  데이터 베이스  >  MySQL 잠금 메커니즘 및 PHP 잠금 메커니즘

MySQL 잠금 메커니즘 및 PHP 잠금 메커니즘

巴扎黑
巴扎黑원래의
2016-11-08 13:39:021051검색

시뮬레이션 준비--스크립트에 대한 높은 동시 액세스를 시뮬레이션하는 방법: Apache 설치 파일의 bin/ab.exe는 동시성 양을 시뮬레이션할 수 있습니다. -c, 동시성이 시뮬레이션되는 양 -n, 총 횟수 http ://요청된 스크립트
예: cmd: apache 설치 경로/bin/ab.exe -c 10 -n 10 http://web.test.com/test.php

[다음으로 이동 포인트]
MYSQL 잠금:
구문:
LOCK TABLE 테이블 이름 1 READ|WRITE, 테이블 이름 2 READ|WRITE ............. [테이블 잠금]
UNLOCK TABLES [테이블 해제]


읽기: 읽기 잠금|공유 잠금: 모든 클라이언트는 이 테이블을 읽을 수만 있고 이 테이블에 쓸 수 없습니다.
쓰기: 쓰기 잠금|배타적 잠금: 모두 현재 잠긴 클라이언트는 해당 테이블을 조작할 수 있으며, 다른 클라이언트는 차단만 가능합니다.
참고: 테이블을 잠그는 동안에는 잠긴 테이블만 조작할 수 있습니다. 잠겨있어!

PHP의 파일 잠금(테이블이 아닌 파일이 잠김)
잠긴 파일과 테이블의 관계는 무엇인가요? : 전혀 관계가 없습니다. 토큰을 얻은 사람이 운영하는 것과 같습니다. 따라서 테이블은 전혀 잠겨 있지 않습니다.
테스트할 때는 파일만 있으면 이름은 중요하지 않습니다.

요약:
프로젝트에서는 PHP에서 파일 잠금만 사용해야 하며 테이블 잠금은 피해야 합니다. 테이블이 잠기면 전체 웹사이트에서 이 테이블과 관련된 모든 기능이 느려지기 때문입니다. (예: 프런트 데스크의 많은 사용자가 주문을 하고 있으며, 제품 테이블 mysql이 테이블을 잠그고 기타 관련 작업이 수행되고 있습니다. 상품 테이블이 차단되었습니다. [상품 테이블을 읽을 수 없습니다], 하나의 기능으로 인해 전체 웹 사이트 속도가 느려지기 때문입니다).

내 프로젝트 중 하나는 O2O 테이크아웃입니다. 오후 12시~2시와 오후 6시는 주문 동시성이 높은 시간입니다. 이 경우 MySQL 잠금은 당연히 고려되지 않으며 사용자 경험도 너무 나쁩니다. 실제로 실제 필요에 따라 테이크아웃용 재고를 설계할 필요는 없습니다. 물론 플래시 세일 활동 모듈 외에도 PHP 파일 잠금이 여전히 필요합니다.

적용 시나리오:
1. 동시성이 높은 주문 시 재고 감소 시 잠금
2. 동시성이 높은 주문이나 티켓 확보 시

MySQL 잠금 사용 샘플 코드:

<?php
/**
模拟秒杀活动-- 商品100件
CREATE TABLE a
(
    id int comment &#39;模拟100件活动商品的数量&#39;
);
INSERT INTO a VALUES(100);
模仿:以10的并发量访问这个脚本!    使用apache自带的ab.exe软件
 */
error_reporting(0);
mysql_connect(&#39;localhost&#39;,&#39;root&#39;,&#39;admin123&#39;);
mysql_select_db(&#39;test&#39;);
# mysql 锁
mysql_query(&#39;LOCK TABLE a WRITE&#39;);// 只有一个客户端可以锁定表,其他客户端阻塞在这
$rs = mysql_query(&#39;SELECT id FROM a&#39;);
$id = mysql_result($rs, 0, 0);
if($id > 0)
{
    --$id;
    mysql_query(&#39;UPDATE a SET id=&#39;.$id);
}
# mysql 解锁
mysql_query(&#39;UNLOCK TABLES&#39;);

PHP 파일 잠금 샘플 코드:

<?php
/**
模拟秒杀活动-- 商品100件
CREATE TABLE a
(
    id int comment &#39;模拟100件活动商品的数量&#39;
);
INSERT INTO a VALUES(100);
模仿:以10的并发量访问这个脚本!    使用apache自带的ab.exe软件
 */
error_reporting(0);
mysql_connect(&#39;localhost&#39;,&#39;root&#39;,&#39;admin123&#39;);
mysql_select_db(&#39;test&#39;);
# php中的文件锁
$fp = fopen(&#39;./a.lock&#39;, &#39;r&#39;); // php的文件锁和表没关系,随便一个文件即可
flock($fp, LOCK_EX);// 排他锁
$rs = mysql_query(&#39;SELECT id FROM a&#39;);
$id = mysql_result($rs, 0, 0);
if($id > 0)
{
    --$id;
    mysql_query(&#39;UPDATE a SET id=&#39;.$id);
}
# php的文件锁,释放锁
flock($fp, LOCK_UN);
fclose($fp);


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.