Détection des blocages et annulation
<<<
Comment gérer les blocages de verrous? Tables InnoDB
>>>

16.11 Modèle de transactions et verrouillage InnoDB
16 Tables InnoDB
 Manuel de Référence MySQL 4.1 : Version Française

InnoDB et AUTOCOMMIT
InnoDB et SET ... TRANSACTION ISOLATION LEVEL ...
Lecture cohérente non-bloquante
Verrous de lecture SELECT ... FOR UPDATE et SELECT ... LOCK IN SHARE MODE
Verrou de clé suivante : éviter le problème des lignes fantômes
Un exemple de lecture cohérente avec InnoDB
Les verrous posés par différentes requêtes SQL avec InnoDB
Quand est-ce que MySQL valide ou annule implicitement une transaction?
Détection des blocages et annulation
->Comment gérer les blocages de verrous?

16.11.10 Comment gérer les blocages de verrous?

Les blocages de verrous sont un problème classique des bases de données transactionnelles, mais ils ne sont pas dangeureux, à moins qu'ils ne se répètent si souvent que vous ne puissiez pas exécuter tranquillement certaines transactions. Normalement, vous devriez écrire vos applications de manière à ce qu'elles soient prêtes à tenter à nouveau une transaction si la transaction est annulée pour cause de blocage.

InnoDB utilise un verrouillage de lignes automatique. Vous pouvez obtenir des blocages sur une ligne, même si votre transactions ne fait que modifier ou insérer une seule ligne. Cela est dû au fait que les opérations ne sont pas réellement 'atomiques' : elles posent automatiquement des verrous (éventuellement plusieurs) sur les lignes d'index de l'enregistrement concerné.

Vous pouvez gérer ces blocages et réduire leur nombre avec les trucs suivants :
  • Utilisez la commande SHOW INNODB STATUS avec MySQL version supérieure à 3.23.52 et 4.0.3, pour déterminer la cause du dernier blocage. Cela peut vous aider à optimiser votre application pour les éviter.
  • Soyez toujours prêts à tenter une nouvelle fois une transaction si elle échoue à cause d'un blocage. Les verrous ne sont pas dangeureux. Essayez juste une autre fois.
  • Validez souvent vos transactions. Les petites transactions sont moins sujettes aux blocages.
  • Si vous utilisez des verrous en lectures avec SELECT ... FOR UPDATE ou ... LOCK IN SHARE MODE , essayez d'utiliser un niveau d'isolation plus bas comme READ COMMITTED .
  • Accédez à vos tables et lignes dans un ordre fixé. Les transactions vont alors former des queues, et non pas des blocages.
  • Ajoutez de bons index à vos tables. Vos requêtes devront scanner moins souvent les tables, et poseront donc moins de verrous. Utilisez EXPLAIN SELECT pour déterminer si MySQL choisit les bons index pour vos requêtes.
  • Limitez votre utilisation des verrous. Si vous pouvez vous permettre de faire retourner à une commande SELECT des données un peu anciennes, n'ajoutez pas la clause FOR UPDATE ou LOCK IN SHARE MODE . Utiliser le niveau d'isolation READ COMMITTED est bon ici, car chaque lecture cohérente dans la même transaction lira avec des données aussi fraîches que possible à chaque fois.
  • En dernier recours, vous pouvez forcer les verrous avec la commande :
    
    LOCK TABLES t1 WRITE, t2 READ, ...;
    [faire quelquechose avec les tables t1 et t2];
    UNLOCK TABLES;
    Les verrous de niveau de table forcent les transactions à se mettre en ligne, et les blocages sont évités. Notez que LOCK TABLES démarre implicitement une transaction, tout comme BEGIN , et UNLOCK TABLES termine une transaction avec un COMMIT .
  • Une dernière solution est de créer un sémaphore auxiliaire sous la forme d'une table avec une seule ligne. Chaque transaction modifie cette table avant d'accéder aux autres tables. Dans ce cas, toutes les transactions se font en ordre séquentiel. Notez que dans cette configuration, même l'algorithme InnoDB de détection des blocages fonctionne, car le sémaphore est un verrou de ligne. Avec les verrous de niveau de table de MySQL, nous devons nous résoudre à une méthode de délai d'expiration pour résoudre un verrou.

<< Comment gérer les blocages de verrous? >>
Détection des blocages et annulation Modèle de transactions et verrouillage InnoDB Tables InnoDB