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 deroomsjusqu'à 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.
-
MyISAMdansMySQL(et plusieurs autres anciens systèmes) verrouille toute la table pendant la durée d'une requête. -
Dans
SQL Server,SELECTles requêtes placent des verrous partagés sur les enregistrements/pages/tables qu'elles ont examinés, tandis queDMLles 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 soitSELECTouDELETEla requête se verrouillera jusqu'à ce qu'une autre session soit validée. -
Dans les bases de données qui utilisent
MVCC(commeOracle,PostgreSQL,MySQLavecInnoDB), unDMLquery 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, unSELECT FOR UPDATEserait pratique :cela verrouillerait soitSELECTou leDELETErequête jusqu'à ce qu'une autre session soit validée, tout commeSQL Serverfait.
Quand faut-il utiliser
REPEATABLE_READisolation des transactions par rapport àREAD_COMMITTEDavecSELECT ... 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
Oracleet versions antérieuresPostgreSQLversions,REPEATABLE READest en fait synonyme deSERIALIZABLE. En gros, cela signifie que la transaction ne voit pas les modifications apportées après son démarrage. Donc dans cette configuration, le dernierThread 1query 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 avecSELECT FOR UPDATE -
Dans
InnoDB,REPEATABLE READetSERIALIZABLEsont des choses différentes :les lecteurs dansSERIALIZABLEle mode définit des verrous de clé suivante sur les enregistrements qu'ils évaluent, empêchant efficacement leDMLsimultané sur eux. Vous n'avez donc pas besoin d'unSELECT FOR UPDATEen mode sérialisable, mais en avez besoin enREPEATABLE READouREAD 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".