Nel mio codice Rails devo confermare che un'azione è consentita solo se è rimasto più di 1 di un determinato record. Per questo motivo ho bisogno di bloccare gli aggiornamenti e quindi eseguire una lettura. Il mio codice di rotaie è simile al seguente:Rails + MySQL + Transactions + Locking, come impedire l'apertura di una transazione dallo sblocco del tavolo?
PaymentProfile.transaction do
profiles = PaymentProfile.lock("LOCK IN SHARE MODE").where(user_id: xxx)
if profiles.count > 1
#allow
else
#do not allow
end
end
In teoria funziona bene e blocca correttamente le righe. TUTTAVIA, se un'altra richiesta attraversa lo stesso percorso di codice che apre la transazione rimuove il blocco che ho eliminato nell'altro processo, vanificando così lo scopo del blocco.
Dalla documentazione MySQL:
Beginning a transaction also causes table locks acquired with LOCK TABLES to be released, as though you had executed UNLOCK TABLES. Beginning a transaction does not release a global read lock acquired with FLUSH TABLES WITH READ LOCK.