Cet article vous apporte des connaissances pertinentes sur MySQL. Il explique principalement comment MySQL met à jour les blocages par lots. Les amis intéressés peuvent jeter un œil ci-dessous. J'espère que cela sera utile à tout le monde.
La structure de la table est la suivante :
CREATE TABLE `user_item` ( `id` BIGINT(20) NOT NULL, `user_id` BIGINT(20) NOT NULL, `item_id` BIGINT(20) NOT NULL, `status` TINYINT(4) NOT NULL, PRIMARY KEY (`id`), KEY `idx_1` (`user_id`,`item_id`,`status`)) ENGINE=INNODB DEFAULT CHARSET=utf-8
L'instruction SQL est la suivante :
update user_item set status=1 where user_id=? and item_id=?
Analyse des causes :
mysql的事务支持与存储引擎有关,MyISAM不支持事务,INNODB支持事务,更新时采用的是行级锁。这里采用的是INNODB做存储引擎,意味着会将update语句做为一个事务来处理。前面提到行级锁必须建立在索引的基础,这条更新语句用到了索引idx_1,所以这里肯定会加上行级锁。 行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。
Cette instruction de mise à jour effectuera les étapes suivantes :
Depuis une clé non primaire index est utilisé, vous devez d'abord obtenir l'idx_1. Le verrouillage au niveau de la ligne
est ensuite mis à jour en fonction de la clé primaire, il est donc nécessaire d'obtenir le verrouillage au niveau de la ligne sur la clé primaire
Après ; la mise à jour est terminée, validez et libérez tous les verrous.
Si une instruction est soudainement insérée entre les étapes 1 et 2 : update user_item…..where id=? et user_id=?, cette instruction verrouillera d'abord l'index de clé primaire, puis verrouillera idx_1.
Une situation douloureuse se présente. Une instruction acquiert le verrou sur idx_1 et attend le verrou sur l'index de clé primaire ; une autre instruction acquiert le verrou sur la clé primaire et attend le verrou sur idx_1, provoquant ainsi un blocage.
Solution :
Répétez la première et la deuxième étapes dans un cycle par lots
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!