Ich zog aus der global aussehenden Datenbank zur nächsten SQL-Abfrage. Ich hoffe, es funktioniert in nächsten Algorithmus: 1) Wählen Sie/nehmen Sie die Sperre von 1 Eintrag aus Tabelle Checkins. 2) Sperren und update usage_flag, so dass ich keine Sorgen über Race Condition.Wie nehmen Sie die Sperre für einen Eintrag?
begin;
SELECT GetDistance('newhaven', area) as distance, id = (SELECT @proxy_id := id)
from checkins
WHERE last_checkin > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
AND active = 1
AND offline = 0
AND usage_flag = 0
ORDER BY distance ASC, RAND() limit 1 FOR UPDATE;
UPDATE checkins set usage_flag=1 where [email protected]_id;
commit;
und aber nach einem Tag in der Produktion, sehe ich eine Tonne Fehler:
'Lock wait timeout exceeded; try restarting transaction'
Wie kann ich diesen Code verbessern, oder vielleicht völlig falsch ich in meinem Mutmaßungen, wie select for update
begin-commit
und arbeitet. Bitte korrigieren Sie mich oder Zeit mich eine Idee, wie es besser geht.
Ihre Anfrage wird Ihre gesamte Tabelle sperren, weil Sie alle Zeilen müssen zum Beispiel berechnen die Bestellung. Ich gehe davon aus, dass Ihre Abfrage länger läuft, sodass Sie direkt ohne explizites Sperren aktualisieren können. Ist dieser Code in einer Prozedur? – Solarflare
@Solarflare Vielen Dank für Ihre Antwort. '' 'Ist dieser Code in einer Prozedur?' '' Nein, es ist eine unabhängige Abfrage. '' 'so können Sie nur direkt ohne explizite Sperre aktualisieren' '' Ich habe eine 300+ Prozesse, die diese Abfrage verwenden, und nicht einen Eintrag auf einmal verwenden möchten, so dass ich definitiv sicher, ich brauche Sperre, aber nicht ganze Tabelle . Vielleicht haben Sie eine Idee, wie Sie es umsetzen können? – comalex3