Mysql
 sql >> Base de données >  >> RDS >> Mysql

Quand utiliser SELECT ... FOR UPDATE ?

Le seul moyen portable d'assurer la cohérence entre les salles et les balises et de s'assurer que les salles ne sont jamais renvoyées après leur suppression est de les verrouiller avec SELECT FOR UPDATE .

Cependant, dans certains systèmes, le verrouillage est un effet secondaire du contrôle de la concurrence et vous obtenez les mêmes résultats sans spécifier FOR UPDATE explicitement.

Pour résoudre ce problème, le fil 1 doit SELECT id FROM rooms FOR UPDATE , empêchant ainsi la suppression de Thread 2 de rooms jusqu'à ce que le fil 1 soit terminé. Est-ce exact ?

Cela dépend du contrôle de concurrence que votre système de base de données utilise.

  • MyISAM dans MySQL (et plusieurs autres anciens systèmes) verrouille toute la table pendant la durée d'une requête.

  • Dans SQL Server , SELECT les requêtes placent des verrous partagés sur les enregistrements/pages/tables qu'elles ont examinés, tandis que DML les requêtes placent des verrous de mise à jour (qui sont ensuite promus en verrous exclusifs ou rétrogradés en verrous partagés). Les verrous exclusifs sont incompatibles avec les verrous partagés, donc soit SELECT ou DELETE la requête se verrouillera jusqu'à ce qu'une autre session soit validée.

  • Dans les bases de données qui utilisent MVCC (comme Oracle , PostgreSQL , MySQL avec InnoDB ), un DML query crée une copie de l'enregistrement (d'une manière ou d'une autre) et généralement les lecteurs ne bloquent pas les rédacteurs et vice versa. Pour ces bases de données, un SELECT FOR UPDATE serait pratique :cela verrouillerait soit SELECT ou le DELETE requête jusqu'à ce qu'une autre session soit validée, tout comme SQL Server fait.

Quand faut-il utiliser REPEATABLE_READ isolation des transactions par rapport à READ_COMMITTED avec SELECT ... FOR UPDATE ?

Généralement, REPEATABLE READ n'interdit pas les lignes fantômes (lignes apparues ou disparues dans une autre transaction, au lieu d'être modifiées)

  • Dans Oracle et versions antérieures PostgreSQL versions, REPEATABLE READ est en fait synonyme de SERIALIZABLE . En gros, cela signifie que la transaction ne voit pas les modifications apportées après son démarrage. Donc dans cette configuration, le dernier Thread 1 query renverra la pièce comme si elle n'avait jamais été supprimée (ce qui peut ou non être ce que vous vouliez). Si vous ne souhaitez pas afficher les pièces après leur suppression, vous devez verrouiller les lignes avec SELECT FOR UPDATE

  • Dans InnoDB , REPEATABLE READ et SERIALIZABLE sont des choses différentes :les lecteurs dans SERIALIZABLE le mode définit des verrous de clé suivante sur les enregistrements qu'ils évaluent, empêchant efficacement le DML simultané sur eux. Vous n'avez donc pas besoin d'un SELECT FOR UPDATE en mode sérialisable, mais en avez besoin en REPEATABLE READ ou READ COMMITED .

Notez que la norme sur les modes d'isolation prescrit que vous ne voyez pas certaines bizarreries dans vos requêtes mais ne définit pas comment (avec verrouillage ou avec MVCC ou autre).

Quand je dis "vous n'avez pas besoin de SELECT FOR UPDATE " J'aurais vraiment dû ajouter "à cause des effets secondaires de l'implémentation de certains moteurs de base de données".