이 기사는 Mysql의 잠금을 안내하고 공유 잠금, 배타적 잠금, 비관적 잠금 및 낙관적 잠금을 이해하고 사용 시나리오에 대해 이야기합니다. 모든 사람에게 도움이 되기를 바랍니다!
1. 일반적인 잠금 유형
테이블 수준 잠금, 테이블 전체 잠금
페이지 수준 잠금, 한 페이지 잠금
행 수준 잠금, 한 행 잠금
공유 잠금, 또한 S 잠금이라고도 하며, MyISAM에서는 읽기 잠금이라고도 합니다
전용 잠금,
일반적인 잠금 유형
실제로는 많은 잠금 유형이 있습니다. mysql의 엔진 유형 중 InnoDB와 MyISAM 엔진이 가장 일반적으로 사용됩니다
MyISAM 엔진은 mysql5.5 버전 이전에 기본적으로 사용되었으나 InnoDB 엔진을 사용하여
다음과 같이 데이터베이스 엔진 명령을 볼 수 있습니다
show variables like '%storage_engine%';
3. 일반적으로 사용되는 엔진의 차이점
MyISAM은 테이블 잠금을 사용하여 데이터를 업데이트할 경우 테이블 전체를 잠가야 하므로 성능이 낮고 동시성이 높지 않습니다. 물론 동시에 교착상태 문제도 발생하지 않습니다.
InnoDB와 MyISAM의 가장 큰 차이점은 두 가지 점입니다. 첫째, InnoDB는 트랜잭션을 지원하고, 둘째, InnoDB는 행 수준 잠금을 사용합니다.
Mysql에서 행 수준 잠금은 레코드를 직접 잠그는 것이 아니라 인덱스를 잠급니다. 인덱스는 기본 키 인덱스와 기본 키가 아닌 인덱스로 구분됩니다. SQL 문이 기본 키 인덱스에서 작동하면 MySQL은 기본 키 인덱스가 아닌 명령문에서 작동하면 기본 키 인덱스를 먼저 잠급니다. 기본 키가 아닌 인덱스를 삭제한 다음 관련 기본 키 인덱스를 잠급니다.
InnoDB 행 잠금은 인덱스 항목을 잠그는 방식으로 이루어집니다. 인덱스가 없으면 InnoDB는 숨겨진 클러스터형 인덱스를 통해 레코드를 잠급니다. 즉, 인덱스 조건을 통해 데이터를 검색하지 않으면 InnoDB는 테이블의 모든 데이터를 잠그며 실제 효과는 테이블 잠금과 동일합니다. 인덱스가 없기 때문에 특정 레코드를 찾으려면 테이블 전체를 스캔해야 하며, 테이블 전체를 스캔하려면 테이블을 잠가야 합니다.
4. 공유 잠금 및 배타적 잠금
기본적으로 데이터베이스 추가, 삭제 및 수정에는 배타적 잠금이 추가되지만 쿼리에서는 잠금이 추가되지 않습니다.
공유 잠금:
특정 리소스에 공유 잠금을 추가합니다. 자신이 리소스를 읽을 수 있고 다른 사람도 리소스를 읽을 수 있습니다. (공유 잠금을 계속 추가할 수도 있습니다. 즉, 여러 공유 잠금이 공존할 수 있습니다.) , 그러나 수정할 수는 없습니다. 수정하려면 모든 공유 잠금이 해제될 때까지 기다려야 합니다.
독점 잠금: 특정 리소스에 단독 잠금을 추가, 삭제, 수정, 확인할 수 있지만 다른 사람은 어떤 작업도 수행할 수 없습니다.
//共享锁
select * from 表名 lock in share mode
//排他锁
select * from 表名 for update
T1: select * from 表名 lock in share mode //假设还未返回结果
T2: update 表名 set name='autofelix'
六、共享锁的实际应用
如果T1和T2都是执行的查询,也就是都加共享锁
这时候就不用等待,可以立马执行
因为同一资源上可以同时存在多个共享锁,也被称为,共享锁与共享锁兼容
意味着共享锁不阻止其他人同时读取资源,但是阻止其他人修改资源
T1: select * from table lock in share mode
T2: select * from table lock in share mode
七、死锁的发生
假设T1和T2都同时执行2个资源操作,分别是查询和更新数据
假设T1和T2同时达到select,T1对表加共享锁,而T2也加上了共享锁
当T1的select执行完毕,准备执行update时
根据锁机制,T1的共享锁必须升级到排他锁才可以执行接下来的update操作
在升级排他锁之前,必须等T2的共享锁释放,同理,T2也在等T1的共享锁释放
于是都在等待对方的锁释放,导致程序卡死,这种情况就是死锁
T1: 开启事务,执行查询更新两个操作
select * from table lock in share mode
update table set column1='hello'
T2: 开启事务,执行查询更新两个操作
select * from table lock in share mode
update table set column1='world'