mécanisme de verrouillage mysql verrouillage optimiste et verrouillage pessimiste, verrouillage partagé et verrouillage exclusif et verrouillage intentionnel et verrouillage de l'écart

Annuaire

Serrure optimiste et serrure pessimiste

Serrure pessimiste

Verrouillage pessimiste - la réalisation dans le tableau de données

Pensée pessimiste élargie

Verrouillage optimiste

Implémentation de verrouillage optimiste dans la table de données

Granularité serrure-serrure optimiste de serrure optimiste

Entraînement optimisé à verrouillage prolongé

Serrure optimiste et serrure pessimiste-petit résumé

Serrure partagée et serrure exclusive et serrure d'intention et serrure de dégagement

Serrure exclusive et serrure partagée

Verrous partagés (verrous partagés, verrous S)

Serrures exclusives (serrures X)

Serrure d'intention

Serrures d'intention

Utilisation du verrouillage d'intention

Serrure de dégagement

Conditions de verrouillage de l'écart

Le rôle du verrouillage de l'écart


Remarque: cet article fait référence à   https://www.jianshu.com/p/904f52bde904

Serrure optimiste et serrure pessimiste

Le contrôle de concurrence optimiste et le contrôle de concurrence pessimiste sont les principales méthodes adoptées par le contrôle de concurrence. Le verrouillage optimiste et le verrouillage pessimiste sont non seulement appliqués dans les bases de données relationnelles, mais ont également des concepts connexes dans Hibernate, Memcache, etc.

Serrure pessimiste

Dans l'architecture actuelle à forte concurrence d'Internet, le verrouillage pessimiste est devenu très rare en raison de l'impact de la réflexion rapide.

Verrouillage pessimiste (verrouillage pessimiste), le verrouillage pessimiste fait référence au processus de traitement des données, de sorte que les données sont dans un état verrouillé, en utilisant généralement le mécanisme de verrouillage de la base de données pour y parvenir.

Verrouillage pessimiste - la réalisation dans le tableau de données

Pour utiliser le verrouillage pessimiste dans MySQL, vous devez désactiver l'autocommit MySQL, définir autocommit = 0, MySQL utilise le mode autocommit autocommit par défaut, c'est-à-dire que vous effectuez une opération de mise à jour, MySQL soumettra automatiquement les résultats.

Prenez une châtaigne:
supposons qu'il y ait une quantité sur le terrain dans le tableau des produits pour indiquer l'inventaire actuel du produit. Supposons qu'il existe un manchon Dulex avec un identifiant de 100 et une quantité = 8; si aucun verrou n'est utilisé, la méthode de fonctionnement

Comme suit:

//step1: 查出商品剩余量
 select quantity from items where id=100;
//step2: 如果剩余量大于0,则根据商品信息生成订单
 insert into orders(id,item_id) values(null,100);
 //step3: 修改商品的库存
 update Items set quantity=quantity-1 where id=100;

Cette façon d'écrire est vraiment normale dans un petit atelier, No Problems, mais des problèmes peuvent survenir dans un environnement à forte concurrence.

Comme suit:

 

En fait, dans le lien ① ou ②, quelqu'un a déjà passé une commande et réduit l'inventaire. À ce stade, l'étape3 est toujours exécutée, ce qui provoque une survente .

Mais l'utilisation de verrous pessimistes peut résoudre ce problème. Dans le scénario ci-dessus, les informations produit sont de la requête à la modification, il y a un processus pour générer des commandes au milieu, le principe de l'utilisation des verrous pessimistes est que lorsque nous interrogeons les informations sur les articles, nous mettons Les données actuelles sont verrouillées jusqu'à ce que nous les modifiions puis les déverrouillions. Ensuite, dans ce processus, car les données sont verrouillées, il n'y aura pas de tiers pour les modifier. La prémisse de ceci est que l'instruction SQL à exécuter doit être placée dans la même chose, sinon le but de verrouiller la ligne de données ne peut pas être atteint.

Comme suit:

//step1: 查出商品状态
select quantity from items where id=100 for update;
//step2: 根据商品信息生成订单
insert into orders(id,item_id) values(null,100);
//step3: 修改商品的库存
update Items set quantity=quantity-2 where id=100;

select ... for update est une méthode fournie par MySQL pour obtenir un verrouillage pessimiste. À ce moment, dans la table des articles, les données avec l'ID de 100 sont verrouillées par nous. Les autres transactions qui doivent exécuter la quantité sélectionnée à partir des articles où id = 100 pour la mise à jour doivent attendre que cette transaction soit exécutée. De cette façon, nous pouvons garantir que les données actuelles ne seront pas modifiées par d'autres transactions.

Pensée pessimiste élargie

Il convient de noter que lorsque j'exécute, sélectionnez la quantité parmi les articles où id = 100 pour la mise à jour. Si j'exécute une quantité sélectionnée à partir d'articles où id = 100 (sans mise à jour) dans la deuxième transaction, les données peuvent toujours être interrogées normalement et ne seront pas affectées par la première transaction. De plus, MySQL a également un problème que toutes les lignes analysées seront verrouillées pendant l'exécution de l'instruction select ... for update, donc l' utilisation du verrouillage pessimiste dans MySQL doit garantir que l'index a disparu, pas l'analyse complète de la table, sinon il le fera Verrouillez l'intégralité du tableau de données .

Le verrouillage pessimiste ne convient à aucune scène, il présente également certaines lacunes, car le verrouillage pessimiste dépend principalement du mécanisme de verrouillage de la base de données pour garantir le degré d'exclusivité maximal. Si le temps de verrouillage est trop long, les autres utilisateurs ne peuvent pas y accéder pendant une longue période, ce qui affecte l'accès simultané du programme. En même temps, cela a également un grand impact sur la surcharge des performances de la base de données, en particulier pour les transactions longues, une telle surcharge est souvent insupportable. Un verrouillage optimiste est requis.

Verrouillage optimiste

Par rapport aux verrous pessimistes, les verrous optimistes pensent que les données ne provoqueront pas de conflits dans des circonstances normales, donc lorsque les données sont soumises pour mise à jour, elles seront formellement vérifiées pour les conflits de données. Si des conflits sont détectés, un message d'erreur sera renvoyé Pour permettre aux utilisateurs de décider comment procéder. Ensuite, nous examinons l'implémentation d'un verrouillage optimiste dans les tables de données et les caches.

Implémentation de verrouillage optimiste dans la table de données

L'utilisation du mécanisme de numéro de version des données (version) est l'une des implémentations de verrouillage optimiste les plus couramment utilisées. Généralement, en ajoutant un champ "version" de type numérique à la table de base de données , lors de la lecture des données, la valeur du champ version est lue ensemble. Chaque fois que les données sont mises à jour, la valeur de la version est +1 . Lorsque nous soumettons une mise à jour, les informations de version actuelle de l'enregistrement correspondant dans la table de base de données sont comparées à la valeur de version récupérée pour la première fois. Si le numéro de version actuelle de la table de base de données est égal à la valeur de version récupérée pour la première fois, elle sera mise à jour. Sinon, elles sont considérées comme des données obsolètes et la mise à jour échoue.

Donnez une châtaigne

//step1: 查询出商品信息
select (quantity,version) from items where id=100;
//step2: 根据商品信息生成订单
insert into orders(id,item_id) values(null,100);
//step3: 修改商品的库存
update items set quantity=quantity-1,version=version+1 where id=100 and version=#{version};

Comme vous pouvez utiliser la version , vous pouvez également utiliser le champ d' horodatage . Cette méthode ajoute également un champ d'horodatage à la table. Similaire à la version ci-dessus, elle vérifie également l'horodatage des données dans la base de données actuelle lorsque la mise à jour est soumise et avant la mise à jour. Comparez les horodatages obtenus, s'ils sont cohérents, puis OK, sinon c'est un conflit de version.

Il convient de noter que si votre table de données est une table distincte pour la lecture et l'écriture, lorsque les données écrites dans la table maître ne sont pas synchronisées avec la table esclave à temps, la mise à jour échouera toujours. À ce stade, vous devez forcer la lecture des données dans la table principale (mettre l'instruction select dans les choses).

C'est-à-dire: mettez l'instruction select dans la transaction et interrogez la bibliothèque principale!

Granularité serrure-serrure optimiste de serrure optimiste

Le verrouillage optimiste est largement utilisé pour la synchronisation des statuts dans notre système d'oiseaux . Nous rencontrons souvent des scénarios où le statut d'un ordre logistique est modifié simultanément, de sorte que le verrouillage optimiste joue un rôle énorme à l'heure actuelle.

Partagez un cas de verrous optimistes soigneusement sélectionnés pour réduire la plage de verrouillage

Lorsque l'inventaire des produits est déduit, en particulier dans les scénarios à concurrence élevée tels que les pics et la rentabilité, si le numéro de version est utilisé comme verrou optimiste, une seule transaction peut être mise à jour avec succès à la fois, et la perception de l'entreprise est un grand nombre d'opérations ayant échoué.

// 仍挑选以库存数作为乐观锁
//step1: 查询出商品信息
select (inventory) from items where id=100;
//step2: 根据商品信息生成订单
insert into orders(id,item_id) values(null,100);
//step3: 修改商品的库存
update items set inventory=inventory-1 where id=100 and inventory-1>0;

C'est vrai! Vous avez participé à Tmall, pic Taobao, et obtenez une bonne affaire. C'est le SQL . En sélectionnant des verrous optimistes, vous pouvez réduire la force de verrouillage et améliorer le débit ~

Le verrouillage optimiste doit être utilisé avec souplesse

Dans l'architecture actuelle à forte concurrence d'Internet, le verrouillage pessimiste est devenu très rare en raison de l'impact de la réflexion rapide.

Entraînement optimisé à verrouillage prolongé

Dans de nombreux systèmes d'Ali, vous pouvez voir les fonctionnalités, paramètres et autres champs couramment utilisés. Si ces champs ne sont pas versionnés, il est très facile d'avoir des problèmes de couverture d'informations dans des scénarios simultanés.

Par exemple:

Thread Caractéristiques originales Caractéristiques cibles
TA a = 1; a = 1; b = 1;
TB a = 1; a = 1; c = 1;

Nous prévoyons que le résultat de la mise à jour finale sera:

a = 1; b = 1; c = 1;

Si SQL est écrit à ce moment

update    
    lg_order
set    
    features=#features#
where    
    order_id=#order_id#

Ensuite, comme l'ordre de TA et TB est différent, le résultat que nous obtenons peut être a = 1; b = 1; ou a = 1; c = 1;

Si vous utilisez un verrouillage optimiste à ce stade et utilisez la version de champ globale pour le traitement, vous constaterez qu'il existe un taux de conflit très élevé avec d'autres champs de lg_order car le champ de version est global

Comment y faire face? ? ?

Intelligent, vous constaterez que lors de la conception de tables de bibliothèque en général, tout ce qui a un champ de fonctionnalités similaire aura un features_cc associé. De nombreux programmeurs plus jeunes en usine prêtent rarement attention à ce champ. Nous avons essayé de le corriger depuis longtemps. , Ça devrait être beaucoup mieux maintenant.

La fonction de features_cc est de contrôler la version de verrouillage optimiste des fonctionnalités, évitant ainsi l'embarras d'utiliser un conflit de version avec l'ensemble du champ.

update    
    lg_order
set    
    features=#features#,    
    features_cc= features_cc +1
where    
    order_id=#order_id#    
    and features_cc =#ori_ features_cc#

Il convient de noter ici que le propriétaire doit examiner attentivement le SQL de sa table associée, en exigeant que toutes les modifications liées au champ des fonctionnalités de cette table soient ajoutées avec features_cc = features_cc +1 pour le calcul, sinon cela provoquera des conflits de concurrence et sera généralement protégé Mesures, sinon gagné l'enchère .

Dans l'environnement réel, il existe de nombreux scénarios à forte concurrence. Voyons si nous avons consciemment ajouté une protection de verrouillage optimiste au champ des fonctionnalités.

Cependant, il convient de mentionner que la culture intensive et le contrôle de ce champ se font au prix d'une augmentation des coûts d'entretien.

Il a fallu beaucoup de temps pour les deux champs de fonctionnalités et d'attribut avant que les étudiants BU n'atteignent le consensus et examinent le code, nécessitant _cc pour le contrôle de version.

Si les changements sont trop fréquents, vous pouvez proposer de les maintenir séparément pour séparer les données chaudes et froides.

Serrure optimiste et serrure pessimiste-petit résumé

  Serrure pessimiste Verrouillage optimiste
Le concept Le verrouillage direct des enregistrements pendant la requête rend impossible l'interrogation et la mise à jour d'autres transactions Vérifiez la version ou l'horodatage lors de la soumission de la mise à jour
La grammaire sélectionnez ... pour la mise à jour Utiliser la version ou l'horodatage pour la comparaison
Réalisateur La base de données elle-même Développeur
Scène applicable Grande simultanéité Faible simultanéité
Analogie Java Mots clés synchronisés Algorithme CAS

Serrure partagée et serrure exclusive et serrure d'intention et serrure de dégagement

Les caractéristiques de la transaction sont visibles: https://blog.csdn.net/xushiyu1996818/article/details/103460349

Serrure exclusive et serrure partagée

Verrous partagés (verrous partagés, verrous S)

Xiaoming a déclaré: Lorsque vous n'avez pas de petite amie, lorsque vous voulez rouler des draps avec une femme, vous ne pouvez aller qu'au quartier rouge, d'autres peuvent également trouver le quartier rouge, c'est du partage!

Le verrou partagé est également appelé verrou en lecture. Si la transaction T1 ajoute le verrou S à la ligne R, alors

Autres transactions T2 / T3 / Tn ne peuvent ajouter qu'un verrou S à la ligne R, pas d'autres verrous

La transaction qui obtient le verrou S ne peut que lire des données, pas écrire des données (vous êtes stupide, bien sûr, vous ne pouvez pas le supprimer).

sélectionnez… verrouiller en mode partage;

Serrures exclusives (serrures X)

Xiaoming a déclaré: Si vous avez de l'argent pour trouver un billet féminin, vous devez monopoliser le billet féminin. D'autres personnes ne peuvent pas l'utiliser. C'est exclusif! Concentrons-nous sur les verrous exclusifs.

Un verrou exclusif est également appelé verrou d'écriture. Si la transaction T1 ajoute un verrou X à la ligne R, alors

Aucune autre transaction T2 / T3 / Tn ne peut ajouter un type de verrou à la ligne R jusqu'à ce que le verrou X sur la ligne R de la transaction T1 soit libéré.

La transaction qui obtient le verrou X peut à la fois lire et écrire des données (vous pouvez également supprimer des données).

sélectionnez ... pour la mise à jour

Remarque: Cette grammaire est également un verrou pessimiste

Exemple de table USER:

id Nom desc
1 Ma Yun L'homme le plus riche
2 Komei Premier négatif

 

// start T1
SELECT * FROM USER WHERE id = 1 lock in share mode; (S锁)
......

// start T2
UPDATE USER SET name = '小明' WHERE id = 1;
......

Si T1 ne se valide pas, le verrou S ne sera pas libéré,
puis T2 fixera le verrou X et attendra que T1 (transaction 1) libère le verrou S.

A ce moment

// 接上文代码块
// start T3
// 此时,如果 T3 做同样查询,可以直接获取S锁进行查询
SELECT * FROM USER WHERE id = 1 lock in share mode; (S锁)

这个时候如果T1(事务1)要进行 DELETE 操作

// start T1
SELECT * FROM USER WHERE id = 1 lock in share mode; (S锁)
......
DELETE FROM USER WHERE id = 1;
......

À ce moment:
T1 constate que le verrou X est occupé par T2, donc T1 ne peut pas obtenir le verrou X et attend que T2 libère le verrou X, et T2 détient le verrou X et attend que T1 libère le verrou S, de sorte que l'attente les uns des autres génère un blocage, deadLock.
Après un blocage, InnoDB générera un message d'erreur et libérera le verrou ( plus tard, il parlera des blocages et des solutions rencontrées dans l'entreprise ).

Le code de verrouillage X ci-dessus peut être affiché avec le diagramme suivant:

Utilisez le flux de temps pour afficher l'interaction des trois threads comme suit:

Serrure d'intention

Serrures d'intention

Xiao Ming a déclaré: Quand il cherche un enseignant ou une étudiante Cang, il doit d'abord vérifier si l'autre partie est partagée ou monopolisée par d'autres, au lieu d'aller voir quelqu'un pour la verrouiller, ce qui peut réduire les coûts!

Le verrouillage d'intention est un verrou de table, qui est principalement utilisé dans innoDB. C'est le comportement de la base de données elle-même. Il ne nécessite pas d'intervention manuelle. Il sera libéré après la fin de la transaction.

Les verrous intentionnels sont divisés en verrous partagés intentionnels (verrous IS) et verrous exclusifs intentionnels (verrous IX)

  • Verrouiller: indique que certaines lignes seront verrouillées dans la transaction
  • Verrou IX: indique que X lignes seront ajoutées à certaines lignes de la transaction

La fonction principale des verrous d'intention est d'améliorer les performances du moteur de stockage. Le verrou S et le verrou X dans innoDB sont des verrous de ligne. Lorsque la transaction arrive, le moteur de stockage doit traverser l'état de verrouillage de toutes les lignes. Les performances étant faibles , le verrou d'intention est introduit . Avant de vérifier le verrouillage de ligne, vérifiez si le verrouillage d'intention existe, s'il existe, bloquez le thread.

Utilisation du verrouillage d'intention

En suivant les idées ci-dessus, regardons la logique utilisée

Donnez une châtaigne

T1:
SELECT * FROM A WHERE id = 1 lock in share mode;(加S锁)

T2:
SELECT * FROM A WHERE id > 0 for update; (加X锁)

En regardant les deux transactions SQL ci-dessus, lorsque T1 est exécuté, un verrou S est ajouté à la ligne id = 1. Avant T2, il est nécessaire d'obtenir le verrou de mise à jour de la table entière pour déterminer, c'est-à-dire:
étape 1: déterminer si la table A a un verrou au niveau de la table
Étape 2: déterminer s'il existe un verrou au niveau des lignes pour chaque ligne du tableau A.
Lorsque la quantité de données est importante (généralement un tableau de 5 à 50 millions de données), ce jugement de l'étape 2 est extrêmement inefficace .

Le linge est tombé! Le linge est tombé! Le linge est tombé! Nous devons donc verrouiller l'accord.

Protocole de verrouillage d'intention

Pour obtenir le verrou S de certaines lignes de la table A, la transaction doit acquérir le verrou IS de la table A

Pour obtenir le verrou X de certaines lignes de la table A, la transaction doit acquérir le verrou IX de la table A

Maintenant! Pour l'
instant, l' étape 2 a changé pour le jugement d'intention
étape 2: a trouvé que la table A a un verrou IS, indiquant que la table doit avoir un verrou S au niveau de la ligne, par conséquent, T2 s'applique pour le blocage du verrou X et attend. Tableau, juger l'efficacité a été grandement améliorée (cela fait-il économiser beaucoup d'argent)

Serrure de dégagement

Un verrou d'espace est un verrou sur un espace entre les enregistrements d'index, ou un verrou sur l'espace avant le premier ou après le dernier enregistrement d'index. Par exemple, SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; empêche d'autres transactions d'insérer une valeur de 15 dans la colonne t.c1, qu'il y ait ou non déjà une telle valeur dans la colonne, car les écarts entre toutes les valeurs existantes dans la plage sont verrouillés.

Lorsque nous utilisons des conditions de plage pour récupérer des données (index non clusterisés, index non uniques) et demander des verrous partagés ou exclusifs, InnoDB verrouille les éléments d'index des enregistrements de données qui remplissent les conditions; Les enregistrements qui n'existent pas sont appelés intervalles, et InnoDB verrouillera également ces intervalles, c'est-à-dire les verrous d'espace.
Les verrous Next-Key sont des verrous de ligne éligibles plus des verrous d'espacement

Conditions de verrouillage de l'écart

Sous InnoDB, le verrouillage de l'écart doit remplir trois conditions:

  • Le niveau d'isolement est RR
  • Lecture actuelle
  • La condition de requête peut aller à l'index

Le rôle du verrouillage de l'écart

Documentation officielle de MySQL: Le but du verrouillage d'écart est d'empêcher d'autres transactions d'ajouter des données à l'écart.

Dans InnoDB en mode RR, le verrouillage de l'écart peut jouer deux rôles:

1. Garantir la récupération et la réplication des données

2. Empêcher la lecture fantôme

  • Empêcher l'exécution des instructions d'insertion dans les espaces
  • Empêcher la mise à jour des données existantes dans l'écart

La récupération et la réplication des données de la base de données sont réalisées via binlog, qui enregistre les instructions DML exécutées avec succès (très largement utilisées dans Alibaba) . Dans la récupération des données, il est nécessaire de garantir la séquence de transactions entre les données, et les verrous d'espace peuvent être évités. Insérez d'autres transactions dans un lot de données.

Publié 524 articles originaux · Comme 80 · Visites 150 000+

Je suppose que tu aimes

Origine blog.csdn.net/xushiyu1996818/article/details/105558662
conseillé
Classement