Domanda

Questo provoca una condizione di competizione con MySQL (InnoDB):

  1. avviare la transazione.

  2. Cercare di ottenere il record.

  3. Se record non esiste, il ritorno.

  4. Se non esiste registrazione, eliminarlo e aggiungere una voce di registro dicendo che è stato eliminato.

  5. Fine transazione (commit / rollback).

E 'possibile per un altro processo per iniziare poco prima della fase di eliminazione nella 2b, rilevare la presenza del record e poi avere entrambi i processi entrano voce eliminare le voci nel registro?

Ci sono precauzioni che devo prendere?

Grazie.

È stato utile?

Soluzione

L'uso 'selezionate per l'aggiornamento' a passaggio 2. Solo un processo sarà in grado di ottenere un blocco sulla riga evitando così lo scenario che hai descritto.

Altri suggerimenti

Journeyman programmatore, credo, ha la soluzione giusta. Dal momento che hai indicato che si sta utilizzando uno strumento ORM rotto (uno che non vi permetterà di ricerca per l'aggiornamento) Io suggerirei che si sposta l'inserire nella tabella di log in un trigger sulla operazione di eliminazione in modo da evitare la duplicazione iscrizione.

avviare la transazione.

Elimina Record / * utilizzando gli stessi criteri utilizzati per 'cercare di ottenere record' * /

se risposta indica record è stato infatti eliminato, aggiungere una voce di registro.

Fine transazione (commit / rollback).

Non è più condizione di competizione.

Sì, è possibile che un'altra transazione per controllare il tavolo dopo aver letto di esso.

Ancora peggio, a causa di come le transazioni funzionano, anche dopo che si elimina la riga, eventuali nuove transazioni che iniziano vedranno la riga perché non si è ancora impegnato l'eliminazione.

SELECT ... FOR UPDATE è un modo per impedirlo.

LOCK TABLE tablename è un altro.

Purtroppo, dal momento che si sta utilizzando un ORM, non ho potuto dire se ha la capacità di fare uno di questi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top