>  기사  >  데이터 베이스  >  Mysql 행 수준 잠금 및 교착 상태 방지 솔루션 사용

Mysql 행 수준 잠금 및 교착 상태 방지 솔루션 사용

黄舟
黄舟원래의
2017-01-18 11:59:291542검색

Mysql 관계형 데이터베이스 관리 시스템

MySQL은 스웨덴 MySQL AB 회사에서 개발한 오픈 소스 소규모 관계형 데이터베이스 관리 시스템입니다. MySQL은 인터넷상의 중소규모 웹사이트에서 널리 사용되고 있습니다. 작은 크기, 빠른 속도, 낮은 총 소유 비용, 특히 오픈 소스의 특성으로 인해 많은 중소 웹 사이트에서는 웹 사이트 총 소유 비용을 줄이기 위해 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;
  }

실제로 단계는 복잡하지 않습니다. 트랜잭션을 시작하고 각 결과가 사실인지 판단한 다음 제출하면 됩니다. 거짓이면 롤백합니다. 단일 배타적 잠금에는 문제가 없습니다. 테이블이 여러 개의 배타적 잠금과 연관되어 있는 경우 교착 상태를 방지하기 위해 주의해야 합니다.

4. 교착 상태

  `id` 기본 키 인덱스

  `name` 인덱스 인덱스

  `age` 공통 필드

 잠금의 근본적인 이유는 두 개 이상의 프로세스가 서로 리소스를 해제해야 하므로 프로세스가 계속 대기하기 때문입니다. 코드에서는 둘 이상의 트랜잭션에서 리소스를 해제하기 위해 다른 트랜잭션이 필요하기 때문입니다.

교착상태에는 상호 배제 조건, 루프 조건, 요청 유지, 부적격 등 4가지 필수 조건이 있으며, 해당 조건 중 하나라도 위반하면 교착 상태가 발생하지 않습니다.

예를 들어 다음 두 문의 첫 번째 문에서는 name이 기본 키 인덱스가 아니고 기본 키 인덱스도 사용되므로 `name` 인덱스를 먼저 사용합니다.

두 번째 문은 기본 키 인덱스를 먼저 사용한 다음 이름 인덱스를 사용합니다. 두 문이 동시에 실행되면 첫 번째 문은 이름 인덱스를 실행하고 두 번째 문이 기본 키 인덱스를 해제할 때까지 기다립니다. 두 번째 문은 기본 키 인덱스를 실행하고 첫 번째 이름 인덱스를 기다리므로 교착 상태가 발생합니다.

해결 방법: 기본 키 값을 기반으로 업데이트되도록 첫 번째 문을 변환합니다.

#①
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 중국어 웹사이트(www.php.cn)를 주목하세요!


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