Maison  >  Article  >  base de données  >  Exemples pour expliquer les verrous partagés et les verrous exclusifs sous MySQL et InnoDB

Exemples pour expliquer les verrous partagés et les verrous exclusifs sous MySQL et InnoDB

WBOY
WBOYavant
2022-02-08 18:00:292332parcourir

Cet article vous apporte des connaissances pertinentes sur les verrous partagés et les verrous exclusifs dans MySQL. J'espère qu'il sera utile à tout le monde.

Exemples pour expliquer les verrous partagés et les verrous exclusifs sous MySQL et InnoDB

Shared Lock

Shared Lock, S Lock, Read Lock sont tous ses noms.

Et j'aime l'appeler Shared Read Lock.

Un verrou partagé (S) permet de lire la transaction qui détient le verrou.

Un verrou partagé permet de lire la transaction détenant le verrou.

Le partage ici c'est, Le partage de lecture .

En d'autres termes, que ce soit au niveau des lignes ou des tables, si un verrou de lecture partagé est placé sur certaines données, D'autres transactions peuvent continuer à lire (c'est-à-dire qu'elles sont autorisées à détenir des verrous de lecture partagés), mais elles ne peut pas écrire, c'est-à-dire lire Écrire l'exclusion mutuelle .

Au fait, permettez-moi de vous présenter comment ajouter un verrou partagé (verrouillage en lecture partagé) :

Verrou partagé au niveau de la table, c'est-à-dire un verrou en lecture partagé au niveau de la table :

select  *  from table(表) lock in share mode ;

Verrou partagé au niveau amont, c'est-à-dire c'est-à-dire un verrou de lecture partagé au niveau de la ligne :

select  *  from table(表)where id = 10  
lock in share mode
 ;

Juste une note rapide, veuillez noter que sous InnoDB, vous n'utilisez pas uniquement des verrous de ligne si vous souhaitez utiliser des verrous de ligne. Revoyons les conditions de déclenchement des verrous de ligne (mentionnées). au début) :

Verrou exclusif (Verrou exclusif)Verrou)

Verrou exclusif, verrou en écriture, verrou X sont tous ses noms.

Et j'aime l'appeler Exclusive Write Lock.

Un verrou exclusif (X) permet à la transaction qui détient le verrou de se mettre à jour ou de supprimer.

Les verrous exclusifs (X) permettent à la transaction détenant le verrou de se mettre à jour ou de supprimer.

Exclusif, ce mot. Avez-vous déjà joué au basket-ball ? Je ne savais pas jouer au basket-ball au collège. Je ne passais pas le ballon pendant que je le tenais. Mes camarades de classe m'ont dit : tu es si seul.

Oui, je suis très seule. Tout comme ce verrou en écriture exclusif (verrouillage exclusif), il est tout à fait unique.

Lorsqu'une transaction ajoute un verrou en écriture exclusif (verrouillage exclusif) à certaines données, seule la transaction en cours peut modifier ou supprimer les données.

Les autres transactions ne peuvent pas être lues ou écrites. Étant donné que ce verrou est unique, vous devez attendre qu'il soit utilisé (libéré) avant que d'autres transactions puissent en profiter.

Ainsi, le verrouillage en écriture exclusif (verrouillage exclusif) est mutuellement exclusif pour la lecture et l'écriture, et mutuellement exclusif pour l'écriture et l'écriture.

Au fait, permettez-moi de vous présenter comment ajouter un verrou exclusif (verrouillage en écriture exclusif) :

Verrou exclusif au niveau de la table, c'est-à-dire un verrou en écriture exclusif au niveau de la table :

select * from table
 for update 
;

Verrou exclusif au niveau amont, qui c'est-à-dire un verrouillage en écriture exclusif au niveau de la ligne :

select * from table where id =10 
 for update
 ;

Permettez-moi d'être un peu plus instructif ici. Notez que sous InnoDB, vous n'utilisez pas uniquement des verrous de ligne si vous souhaitez utiliser des verrous de ligne. encore une fois (mentionné au début) :

Le SQL ci-dessus peut obtenir un verrou exclusif au niveau de la ligne car il atteint l'index, et l'identifiant est l'index.


Peut-être que lorsque vous voyez cela, vous êtes encore vague sur les verrous partagés et les verrous exclusifs. Vous savez à peu près ce qu'est le partage en lecture-lecture, l'exclusion mutuelle en lecture-écriture, l'exclusion mutuelle en écriture-écriture, etc.

Nous devons donc examiner à nouveau ces deux verrous du point de vue de Dieu,

rouge Opération de transaction un

bleu Opération de transaction deux


Verrouillage partagé (verrouillage de lecture partagé) Verrouillage exclusif (verrouillage d'écriture exclusif)
Verrouillage partagé (verrouillage de lecture partagé) Oui, compatible, lire ensemble Non, incompatible. Si vous voulez écrire, vous devez attendre que le verrou partagé disparaisse
Verrou exclusif (verrouillage en écriture exclusif) Non, non compatible avec le verrou exclusif, les autres ne peuvent rien déplacer Non. , non compatible , avec la serrure exclusive, personne d'autre ne peut toucher à quoi que ce soit

那么如果你看到这里,还是对 共享锁  & 排他锁还只是云里雾里。

那我只有动手了!

实战介绍,演示 所谓的读读共享、读写互斥、写写互斥 。

在演示读读共享、读写互斥、写写互斥前, 我必须点明一点!

在这篇文章里面,我介绍了一些上 共享锁(共享读锁)、排他锁(独占写锁)的方式 。 但是 可以看到写的查询sql 都是后面加了东西的 ,  lock in share mode ,for update  .... 等。

所以我想点明的一点是,

  如果是使用 普通的查询 ,是 什么锁都没上的!

就好像平时我们经常写的

select * from table ;
select * from table where age=18;

select语句默认不会加任何锁类型

select语句默认不会加任何锁类型

select语句默认不会加任何锁类型

而排他锁,除了 select .... for update ,InnoDB引擎 默认的修改 、插入、删除(update,insert,delete)都是会给操作的相关数据 加 排他锁的 .

废话不多说,我们上才艺:

准备一些用于测试的数据。

建表:

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `sex` tinyint(1) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

搞点模拟数据:


(id主键索引)

第一个小实践:

我们不废话,我们直接上共享读锁, 看看是不是能 符合刚才我们的理论 读读共享,读写互斥

1. 我们先给id=3这数据上个 共享读锁:

2.基于当前状况, 我们再执行一下查询语句,也是使用共享读锁的:

3.那么也是基于当前情况,我们再执行一下使用排他写锁的查询语句,可以发现 读写互斥了:

4.验证下,我们查看当前是否存在事务在等待锁:

可以从结果中看出 事务请求id 34847在等待锁:

我们再查询一下,那些事务在使用锁,
可以从结果看出,34844事务在使用S锁,也就是共享读锁;

而34847事务 在使用 X锁, 也就是排他写锁(但是由于共享读锁先上了,所以读写互斥了),所以造成了34847事务 在等待锁。

5.那么如果我们一直不 COMMIT 共享读锁, 34847事务 会永无止息地等待锁吗?   那么肯定是不可能允许这种一直等待的场景的:

所以mysql会有个等待锁资源超时的机制,这种情况就会直接返回查询失败的结果。

根据第一个小实践,我们得出一个很明显的结论:

当某数据上了 共享读锁 S 时, 只允许其他事务上共享读锁 S, 因为读读共享;

不允许其他事务上 独占写锁 X(除非把这个共享读锁S 释放掉),因为读写互斥。

第二个小实践:

1.我们直接给某行数据上个排他写锁 X (注意我们的事务是没有执行COMMIT的) :

2. 我们接下来去 通过共享读锁去获取数据,看看会发生什么?

这就是 独占写锁 X 的 读写互斥、写写互斥 (写写互斥的场景就不展示了).

再验证下,我们看下是不是存在事务在等待锁资源:

3. Donc, si le verrou d'écriture exclusif n'est jamais libéré, les autres transactions continueront-elles d'attendre ?

La même chose est vraie, il attendra le délai d'attente pour renvoyer un échec de requête :

Ajoutez un peu de pratique :

1 Toujours pareil, donnez d'abord un verrou en écriture exclusif sur certaines données sans COMMIT :

.

2. Exécutez la requête ordinaire, sélectionnez :

Vous pouvez voir que l'instruction select ordinaire peut être obtenue normalement, pourquoi ? Parce que nous l'avons déjà mentionné :

Je dois donc l'expliquer à nouveau. Le soi-disant partage en lecture-lecture, l'exclusion mutuelle en lecture-écriture et l'exclusion mutuelle en écriture sont tous destinés aux ressources de verrouillage. S'il n'y a pas de concurrence pour les ressources verrouillées, alors il ne doit pas y avoir d'exclusion mutuelle ou d'exclusion mutuelle.

Apprentissage recommandé : Tutoriel vidéo mysql

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer