Ciò è scaturito da questa domanda correlata , in cui volevo sapere come forzare due transazioni in modo sequenziale in un caso banale (in cui entrambi operano su una sola riga). Ho ricevuto una risposta, utilizzare SELECT ... FOR UPDATE
come prima riga di entrambe le transazioni, ma ciò porta a un problema: se la prima transazione non viene mai impegnata o ripristinata, la seconda transazione verrà bloccata indefinitamente. La innodb_lock_wait_timeout
variabile imposta il numero di secondi dopo i quali al client che tenta di effettuare la seconda transazione verrà detto "Scusa, riprova" ... ma per quanto ne so, ci riproverebbero fino al riavvio del server successivo. Così:
- Sicuramente ci deve essere un modo per forzare un
ROLLBACK
se una transazione sta prendendo per sempre? Devo ricorrere all'uso di un demone per uccidere tali transazioni e, in tal caso, come sarebbe un demone simile? - Se una connessione viene interrotta da
wait_timeout
o durante lainteractive_timeout
transazione, viene ripristinata la transazione? C'è un modo per testarlo dalla console?
Chiarimento : innodb_lock_wait_timeout
imposta il numero di secondi in cui una transazione attenderà il rilascio di un blocco prima di rinunciare; quello che voglio è un modo per forzare il rilascio di un lucchetto.
Aggiornamento 1 : ecco un semplice esempio che dimostra perché innodb_lock_wait_timeout
non è sufficiente per garantire che la seconda transazione non sia bloccata dalla prima:
START TRANSACTION;
SELECT SLEEP(55);
COMMIT;
Con l'impostazione predefinita di innodb_lock_wait_timeout = 50
, questa transazione si completa senza errori dopo 55 secondi. E se aggiungi una UPDATE
prima della SLEEP
riga, quindi avvia una seconda transazione da un altro client che tenta SELECT ... FOR UPDATE
la stessa riga, è la seconda transazione a scadere, non quella che si è addormentata.
Quello che sto cercando è un modo per forzare la fine del sonno riposante di questa transazione.
Aggiornamento 2 : in risposta alle preoccupazioni di hobodave su quanto sia realistico l'esempio sopra, ecco uno scenario alternativo: un DBA si collega a un server live ed esegue
START TRANSACTION
SELECT ... FOR UPDATE
dove la seconda riga blocca una riga in cui l'applicazione scrive frequentemente. Quindi il DBA viene interrotto e si allontana, dimenticando di terminare la transazione. L'applicazione si ferma fino a quando la riga non viene sbloccata. Vorrei ridurre al minimo il tempo in cui l'applicazione è bloccata a causa di questo errore.
ROLLBACK
sulla prima transazione se il completamento richiede più di n
secondi. C'è un modo per farlo?
MYSQL
abbia una configurazione per prevenire questo scenario. Perché non è accettabile il blocco del server a causa dell'irresponsabilità dei client. Non ho trovato alcuna difficoltà a capire la tua domanda, anche se è così rilevante.