Question

Est-ce que cette cause une condition de course avec MySQL (InnoDB):

  1. Lancer la transaction.

  2. Essayez d'obtenir dossier.

  3. Si enregistrement n'existe pas, le retour.

  4. Si enregistrement existe, supprimez-le et ajoutez une entrée de journal disant qui est a été supprimé.

  5. Fin de la transaction (commit / rollback).

Est-il possible pour un autre processus pour commencer juste avant l'étape de suppression dans 2b, détecter la présence du dossier et ensuite les deux processus entrent élément de supprimer des entrées dans le journal?

Y a-t-il des précautions que je dois prendre?

Merci.

Était-ce utile?

La solution

Utilisez « sélectionner pour la mise à jour » à l'étape 2. Un seul processus sera en mesure d'obtenir un verrou sur la ligne évitant ainsi le scénario que vous avez décrit.

Autres conseils

Journeyman programmeur, je crois, a la bonne solution. Puisque vous avez indiqué que vous utilisez un outil ORM cassé (celle qui ne vous permettra pas d'interroger la mise à jour) Je vous suggère que vous déplacez votre insertion dans la table de journal dans un déclencheur sur l'opération de suppression afin que vous éviterez le double entrée.

Lancer la transaction.

Supprimer l'enregistrement / * en utilisant les mêmes critères que vous utilisez pour « essayer d'obtenir l'enregistrement » * /

si la réponse indique enregistrement a en effet été supprimé, ajoutez une entrée de journal.

Fin de la transaction (commit / rollback).

Plus de condition de course.

Oui, il est possible pour une autre transaction pour vérifier la table après que vous l'avez lu.

Pire encore, en raison de la façon dont fonctionnent les transactions, même après avoir supprimé la ligne, toutes les nouvelles opérations qui commencent verront la ligne parce que vous ne l'avez pas encore engagé la suppression.

SELECT ... FOR UPDATE est une façon de l'empêcher.

LOCK TABLE tablename est une autre.

Malheureusement, puisque vous utilisez un ORM, je ne pouvais pas dire si elle a la capacité de faire l'une de ces.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top