2016-03-19 9 views
1

Bitte geben Sie einen Hinweis auf das folgende Problem: Ich habe eine Liste von eindeutigen Codes. Der Code muss nur einmal verwendet werden, daher ist jedem Code ein Status zugeordnet (verwendet/nicht verwendet).SQL - um zu sperren oder nicht zu sperren: nächsten unbenutzten Code auswählen

Ich mache mir Sorgen über Konkurrenz/Race Conditions, wenn mehrere Threads versuchen werden, nächsten unbenutzten Code zu bekommen.

Was ist der beste Weg, um es mit SQL-Datenbank (MySQL in meinem Fall) zu implementieren?

Die erste Option Sperren zu verwenden ist und schreib engagierte Isolationsstufe:

start transaction in read-committed isolation level 
select code from code_table where status = 'not-used' for update 
update code_table set status = 'used' where code = :code 
commit transaction 

Im Fall des Anstoßes der Fäden, wie ich glaube, dass „Datenbank-Threads“ auf der gesperrte Zeile stolpern, wartet, wenn die Zeilenschreibsperre nicht freigegeben wird, wird (aufgrund der Read-Committed-Isolationsstufe) sehen, dass dieser Code-Datensatz bereits verwendet wird, und zu anderen Code-Datensätzen weitergehen.

Die zweite Option ähnelt etwas zu verwenden, das optimistische Sperren in den Ruhezustand (wir verwenden Hibernate nicht), hier ist die Beschreibung der einzelnen Schritte:

start transaction in default isolation level (read-repeatable) 
select code from code_table where status = 'not-used' 
commit transaction 

start transaction in default isolation level (read-repeatable) 
update code_table set status = 'used' where code = :code 
commit transaction 

In Java-Code werde ich überprüfen, wie viel Datensätze wurden aktualisiert. Wenn ein Datensatz aktualisiert wird, ist alles in Ordnung, wenn 0 Datensätze aktualisiert sind - wiederhole ich den Schritt..nach der 3. (oder 5.) Probe - eine Ausnahme auslösen.

Jede Hilfe/Beratung würde sehr geschätzt werden. Vielen Dank im Voraus

+0

Ok, entfernte sql-server .... – user3489820

Antwort

2

Die zweite Option - optimistisches Sperren - scheint eine ziemlich schlechte Idee zu sein.
von wikipedia: https://en.wikipedia.org/wiki/Optimistic_concurrency_control

optimistisch Concurrency Control (OCC). . . . . . .
. . . . . . . . wird im Allgemeinen in Umgebungen mit niedrigen Datenkonflikt verwendet. Wenn Konflikte selten sind, können Transaktionen ohne die Kosten der Verwaltung von Sperren und abgeschlossen werden, ohne Transaktionen warten auf Sperren anderer Transaktionen auf deaktivieren, was zu einem höheren Durchsatz als andere Nebenläufigkeitskontrolle Methoden. Jedoch, , wenn Konkurrenz für Datenressourcen häufig ist, die Kosten des wiederholten Neustarts von Transaktionen beeinträchtigt die Leistung deutlich; Es wird allgemein angenommen, dass andere Methoden zur Gleichzeitigkeitskontrolle unter diesen Bedingungen eine bessere Leistung zeigen. Locking-basierte ("pessimistische") Methoden können jedoch auch eine schlechte Leistung liefern, da das Sperren die effektive Gleichzeitigkeit drastisch einschränken kann, selbst wenn Deadlocks vermieden werden.

Ich kann das folgende Szenario mit X gleichzeitigen Threads leicht vorstellen:

  • Thread # 1 bekommt eine nächste nicht verwendete Datensatz # 1
  • Thread # 2 bekommt eine nächste nicht verwendete Datensatz # 1
  • Thread # 3 erhält einen nächsten nicht verwendeten Datensatz # 1
  • Gewinde # 4 g ets eine nächste nicht verwendete Datensatz # 1
    .....
    .....
  • Thread # 1 aktualisiert den Datensatz # 1, nimmt dann nächsten verfügbaren Datensatz # 2
  • Faden # 2 erfasst eine Kollision beim Versuch, den Datensatz # 1, so Neuversuche und nächsten verfügbaren Datensatz nimmt zu aktualisieren # 2
  • Gewinde # 3 erfasst eine Kollision beim Versuch, den Datensatz # 1, so Neuversuche und nimmt nächsten verfügbaren Datensatz # 2
  • Gewinde # 4 erfasst eine Kollision zu aktualisieren beim Versuch, den Datensatz # 1, so Neuversuche und nimmt weiter zu aktualisieren, verfügbar Rekord # 2 .....
    .....
    .....
    und so weiter, und so weiter. Viele Konflikte und Wiederholungen.

Sie müssen die erste Option bleiben.
Um Konflikte zu reduzieren, möchten Sie Transaktionen möglicherweise so kurz wie möglich halten.

+0

danke! Wir haben die erste Option implementiert, aber es ist gut, jemanden bestätigt zu haben. – user3489820