MySQL数据库锁介绍_MySQL
bitsCN.com
MySQL数据库锁介绍
1. 锁的基本概念
当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性。
锁就是其中的一种机制。
我们可以用商场的试衣间来做个比喻。商场里得每个试衣间都可供多个消费者使用,因此可能出现多个消费者同时试衣服需要使用试衣间。为了避免冲突,试衣间装了锁,某一个试衣服的人在试衣间里把锁锁住了,其他顾客就不能再从外面打开了,只能等待里面的顾客,试完衣服,从里面把锁打开,外面的人才能进去。
2. 锁的基本类型
数据库上的操作可以归纳为两种:读和写。
多个事务同时读取一个对象的时候,是不会有冲突的。同时读和写,或者同时写才会产生冲突。因此为了提高数据库的并发性能,通常会定义两种锁:共享锁和排它锁。
2.1 共享锁(Shared Lock,也叫S锁)
共享锁(S)表示对数据进行读操作。因此多个事务可以同时为一个对象加共享锁。(如果试衣间的门还没被锁上,顾客都能够同时进去参观)
产生共享锁的sql:select * from ad_plan lock in share mode;
2.2 排他锁(Exclusive Lock,也叫X锁)
排他锁也叫写锁(X)。
排他锁表示对数据进行写操作。如果一个事务对对象加了排他锁,其他事务就不能再给它加任何锁了。(某个顾客把试衣间从里面反锁了,其他顾客想要使用这个试衣间,就只有等待锁从里面给打开了)
产生排他锁的sql: select * from ad_plan for update;
对于锁,通常会用一个矩阵来描述他们之间的冲突关系。
S X
S + –
X – –
+ 代表兼容, - 代表不兼容
时间/事务
Tx1:
Tx2:
T1set autocommit=0;set autocommit=0;T2select * from ad_plan lock in share mode;T3update ad_plan set name='' ; blocking
执行sql: select * from information_schema.innodb_locks; 可以查看锁。
3. 锁的粒度
就是通常我们所说的锁级别。MySQL有三种锁的级别:页级、表级、行级。
相对其他数据库而言,MySQL的锁机制比较简单,其最 显著的特点是不同的存储引擎支持不同的锁机制。
比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。
MySQL这3种锁的特性可大致归纳如下:
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
数据库引擎通常必须获取多粒度级别上的锁才能完整地保护资源。
3.1 行锁(Row Lock)
对一行记录加锁,只影响一条记录。
通常用在DML语句中,如INSERT, UPDATE, DELETE等。
InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
用下面例子来说明一下:
CREATE TABLE test_index(id int , name VARCHAR(50),age int )engine=innodb ;INSERT INTO test_index values(1,'张一',15);INSERT INTO test_index values(3,'张三',16);INSERT INTO test_index values(4,'张四',17);INSERT INTO test_index values(5,'张五',19);INSERT INTO test_index values(7,'刘琦',19);
不再启用多事务描述了,直接解释执行查询语句
explain select * from test_index where id = 1;+----+-------------+------------+------+---------------+------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+------------+------+---------------+------+---------+------+------+-------------+| 1 | SIMPLE | test_index | ALL | NULL | NULL | NULL | NULL | 5 | Using where |+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
type: all ,rows: 5 很明显是会使用全表锁。
增加索引,id加唯一索引,age加普通索引。
ALTER TABLE test_indexADD UNIQUE uk_id(id),ADD index idx_age(age);mysql> explain select * from test_index where id = 1;+----+-------------+------------+-------+---------------+-------+---------+-------+------+-------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+------------+-------+---------------+-------+---------+-------+------+-------+| 1 | SIMPLE | test_index | const | uk_id | uk_id | 5 | const | 1 | NULL |+----+-------------+------------+-------+---------------+-------+---------+-------+------+-------+type: const ,key:uk_id,rows:
1 很明显是会使用行锁,锁定一条记录。
下面做个有趣的实验:两个事务,TX1加共享行锁, 查询age=17的记录, TX2往数据库里插入一条age=18的记录。
TX1:mysql> set autocommit=0;mysql> select * from test_index where age=17 lock in share mode;+------+------+------+| id | name | age |+------+------+------+| 4 | 张四 | 17 |+------+------+------+1 row in set (0.00 sec)TX2:mysql> set autocommit=0;mysql> insert test_index values(8,'test',18);ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
结果是TX2获取锁超时,看来TX1锁定的并不止age=17的记录,不存在的间隙age=18,也被加锁了。
执行select * from information_schema.innodb_locks;可以看到加锁的具体信息
+--------------+-------------+-----------+-----------+---------------------+------------+------------+-----------+----------+--------------------+| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |+--------------+-------------+-----------+-----------+---------------------+------------+------------+-----------+----------+--------------------+| 45288:57:5:5 | 45288 | X,GAP | RECORD | `test`.`test_index` | idx_age | 57 | 5 | 5 | 19, 0x000000000208 || 45289:57:5:5 | 45289 | S,GAP | RECORD | `test`.`test_index` | idx_age | 57 | 5 | 5 | 19, 0x000000000208 |+--------------+-------------+-----------+-----------+---------------------+------------+------------+-----------+----------+--------------------+
行锁S、X锁上做了一些精确的细分,在代码中称作Precise Mode。这些精确的模式, 使的锁的粒度更细小。可以减少冲突。
A.间隙锁(Gap Lock),只锁间隙。
B.记录锁(Record Lock) 只锁记录。
C.Next-Key Lock(代码中称为Ordinary Lock),同时锁住记录和间隙。
D.插入意图锁(Insert Intention Lock),插入时使用的锁。在代码中,插入意图锁,实际上是GAP锁上加了一个LOCK_INSERT_INTENTION的标记。
行锁兼容矩阵
G I R N
G + + + +
I – + + –
R + + – –
N + + – –+ 代表兼容, -代表不兼容.
G代表Gap锁,I代表插入意图锁,R代表记录锁,N代表Next-Key锁.
S锁和S锁是完全兼容的,因此在判别兼容性时不需要对比精确模式。
精确模式的检测,用在S、X和X、X之间。
从这个矩阵可以看到几个特点:
A. INSERT操作之间不会有冲突。
B. GAP,Next-Key会阻止Insert。
C. GAP和Record,Next-Key不会冲突
D. Record和Record、Next-Key之间相互冲突。
E. 已有的Insert锁不阻止任何准备加的锁。
Gap lock:
间隙锁只会出现在辅助索引(index)上,唯一索引(unique)和主键索引是没有间隙锁。
间隙锁(无论是S还是X)只会阻塞insert操作。
间隙锁的目的是为了防止幻读(但是需要应用自己加锁,innodb默认不会加锁防止幻读)。
3.2 页面锁
3.3 表锁(Table Lock)
对整个表加锁,影响标准的所有记录。通常用在DDL语句中,如DELETE TABLE,ALTER TABLE等。
很明显,表锁影响整个表的数据,因此并发性不如行锁好。
在MySQL 数据库中,使用表级锁定的主要是MyISAM,Memory等一些非事务性存储引擎。
因为表锁覆盖了行锁的数据,所以表锁和行锁也会产生冲突(商场关门了,试衣间自然也没法使用了)。如:
A. trx1 BEGIN
B. trx1 给 T1 加X锁,修改表结构。
C. trx2 BEGIN
D. trx2 给 T1 的一行记录加S或X锁(事务被阻塞,等待加锁成功)
trx1要操作整个表,锁住了整个表。那么trx2就不能再对T1的单条记录加X或S锁,去读取或修这条记录。
3.3.1 表锁—意向锁
为了方便检测表级锁和行级锁之间的冲突,就引入了意向锁。
A. 意向锁分为意向读锁(IS)和意向写锁(IX)。
B. 意向锁是表级锁,但是却表示事务正在读或写某一行记录,而不是整个表。 所以意向锁之间不会产生冲突,真正的冲突在加行锁时检查。
C. 在给一行记录加锁前,首先要给该表加意向锁。也就是要同时加表意向锁和行锁。
采用了意向锁后,上面的例子就变成了:
A. trx1 BEGIN
B. trx1 给 T1 加X锁,修改表结构。
C. trx2 BEGIN
D. trx2 给 T1 加IX锁(事务被阻塞,等待加锁成功)
E. trx2 给 T1 的一行记录加S或X锁.
表锁的兼容性矩阵
IS IX S X
IS + + + –
IX + + – –
S + – + –
X – – – –+ 代表兼容, -代表不兼容
意向锁之间不会冲突, 因为意向锁仅仅代表要对某行记录进行操作。在加行锁时,会判断是否冲突。
bitsCN.com

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











115 네트워크 디스크에는 많은 리소스가 있을 것인데 리소스를 찾는 방법은 무엇입니까? 사용자는 소프트웨어에서 필요한 리소스를 검색한 다음 다운로드 인터페이스로 들어간 다음 네트워크 디스크에 저장하도록 선택할 수 있습니다. 115 네트워크 디스크에서 리소스를 찾는 방법에 대한 이 소개는 구체적인 내용을 알려줄 수 있습니다. 다음은 자세한 소개입니다. 와서 살펴보세요. 115 네트워크 디스크에서 리소스를 찾는 방법 답변: 소프트웨어에서 콘텐츠를 검색한 다음 클릭하여 네트워크 디스크에 저장합니다. 자세한 소개: 1. 먼저 앱에서 원하는 리소스를 입력하세요. 2. 그러면 나타나는 키워드 링크를 클릭하세요. 3. 그런 다음 다운로드 인터페이스로 들어갑니다. 4. 내부 네트워크 디스크에 저장을 클릭합니다.

한샤오취안은 한국 드라마를 많이 볼 수 있는 소프트웨어인데 왜 갑자기 리소스가 없나요? 이 소프트웨어는 네트워크 문제, 버전 문제 또는 저작권 문제로 인해 리소스가 없을 수 있습니다. Han Xiaoquan이 갑자기 자원이 없는 이유에 대한 이 기사는 구체적인 내용을 알려줄 수 있습니다. 다음은 자세한 소개입니다. 와서 살펴보세요. Han Xiaoquan에 갑자기 리소스가 없는 이유는 무엇입니까? 답변: 네트워크 문제, 버전 문제 및 저작권 문제로 인해 자세한 소개: 1. 네트워크 문제 해결 방법: 다른 네트워크를 선택한 다음 소프트웨어에 다시 로그인하여 시도해 볼 수 있습니다. . 2. 버전 문제 해결: 사용자는 공식 웹사이트에서 이 소프트웨어의 최신 버전을 다운로드할 수 있습니다. 3. 저작권 문제 해결: 저작권 문제로 인해 일부 한국 드라마가 목록에서 제거되었습니다. 다른 한국 드라마를 선택하여 시청할 수 있습니다.

Windows 11의 안전 모드에서 Explorer.exe가 충돌합니까? 더 이상은 아닙니다. Microsoft는 방금 Dev 채널에 대한 새 패치를 출시했습니다. 이 릴리스에는 새로운 기능이 없지만 Explorer.exe가 안전 모드에서 충돌하는 성가신 버그를 포함하여 Windows 참가자 프로그램에 많은 수정 및 개선 사항이 적용되고 있습니다. 이제 적어도 Windows Insider 프로그램에서는 작별 인사를 할 수 있습니다. 그러나 이러한 모든 업데이트와 마찬가지로 Windows 서버에도 적용될 예정입니다. Explorer.exe가 안전 모드에서 작동하지 않는 문제를 해결했습니다. 그러나 파일 탐색기에는 몇 가지 다른 수정 사항이 있으므로 Microsoft는 이를 작동시키려고 합니다.

Dying Light 게임에서는 자원 부족으로 인해 많은 플레이어가 초기 단계에서 수많은 좀비에 둘러싸여 있을 수 있습니다. 때때로 그들은 갇힌 방랑자를 구출하기 위해 위험을 감수할 수도 있으며, 이 방랑자는 또한 완료 후 풍부한 보상을 받게 될 몇 가지 부차적인 작업을 제공할 수도 있습니다. 다잉라이트 자원 무제한 획득 먼저 구호 꾸러미를 찾아 창고에 넣어두세요. [인벤토리] 홈페이지에서 수량이 많은 아이템을 선택하고, 선택되면 마우스 왼쪽 버튼을 클릭하세요. 2. 그런 다음 마우스를 움직이지 않고 빠르게 F+A를 누르세요. 약 0.25초 후에 창고 페이지가 나올 것 같으면 마우스 왼쪽, 오른쪽 버튼을 누르세요. .마우스를 움직이지 말고 길게 누르지 마세요. 아이템을 저장하라는 메시지가 뜨고 성공합니다. 3마지막으로 창고에서 [재난 패키지]를 찾으면 다음 메시지가 표시됩니다.

기본 원칙: Go 언어 자체는 그래픽 인터페이스 개발을 직접 지원하지 않지만, 다른 언어의 라이브러리를 호출하거나 기존 도구를 사용하여 그래픽 인터페이스 개발을 달성할 수 있습니다. 이 기사에서는 독자가 그래픽 인터페이스 개발에 Go 언어를 사용할 가능성을 더 잘 탐색할 수 있도록 일반적으로 사용되는 몇 가지 도구와 리소스를 소개합니다. 1. Go 언어 그래픽 인터페이스 개발 현황 Go 언어는 효율적이고 간결한 프로그래밍 언어로 다양한 응용 분야에 적합하지만 그래픽 인터페이스 개발에는 적합하지 않습니다. Go 언어의 성능 및 동시성 기능으로 인해 많은 개발자가

이제 ChatGPT는 더 이상 플러스 결제를 지원하지 않습니다. △ChatGPT 스크린샷을 찍은 이유는 매우 간단하다. 수요가 많다는 점이다. 수요가 너무 높아서 OpenAI는 Plus의 판매를 중단해야 했습니다. 나중에 언제 오픈할지는 아직 알려진 바가 없습니다. 며칠 전 ChatGPT는 대규모 계정 정지로 인해 열띤 토론을 벌였고, 이제 공식적으로 플러스 유료 멤버십 신청을 종료했습니다. 많은 네티즌들은 이를 컴퓨팅 자원 부족 때문이라고 생각하는데, 이는 더 이상 돈만으로는 해결할 수 없는 문제입니다. 재정적 후원자인 Microsoft도 자체 사용자 기반을 제공해야 합니다. 더 이상 지구상에는 수요를 충족할 만큼 충분한 컴퓨팅 성능이 없습니다. 이미 비용을 지불한 일부 네티즌들은 “GPT-3.5 시절로 돌아가는 건 정말 상상할 수 없다”며 감사의 뜻을 표했다. ChatGPT closePlu

Java는 애플리케이션을 개발하고 웹 사이트를 만드는 데 널리 사용되는 프로그래밍 언어입니다. 그러나 Java 애플리케이션을 개발하고 배포할 때 다음 오류가 발생할 수 있습니다. 애플리케이션 리소스를 찾을 수 없습니다. 이 오류는 Java 애플리케이션을 패키징하고 배포할 때 자주 발생합니다. 이 문서에서는 이 오류를 방지하는 원인, 해결 방법 및 방법에 대해 설명합니다. 오류 원인 응용 프로그램 리소스를 찾을 수 없음 오류는 일반적으로 다음과 같은 이유로 인해 발생합니다. 1.1 파일이 없거나 손상되었습니다: 응용 프로그램 패키지 또는 종속 라이브러리 파일이 없거나 손상된 경우,

프로그래밍 언어로서 Python에 대한 수요로 인해 Python의 다양한 측면을 학습할 수 있는 풍부한 리소스가 탄생했습니다. 초보자가 시작하는 데 도움이 되는 다양한 튜토리얼과 가이드가 있지만 고급 학습자는 특정 요구 사항을 충족하는 리소스를 찾는 데 어려움을 겪는 경우가 많습니다. 이 기사에서는 고급 언어 기능, 디자인 패턴, 성능 최적화 등과 같은 주제를 다루면서 Python 기술을 향상시키기 위해 고안된 일련의 리소스를 살펴보겠습니다. 고급 Python 언어 기능Python을 최대한 활용하려면 고급 언어 기능을 숙달하는 것이 중요합니다. 이러한 기능은 효율적이고 현실적으로 가능합니다.
