2016-07-11 15 views
1

Ich bin auf der Suche nach einer effizienten Möglichkeit zur Implementierung von Compare-and-Swap-Operationen in Berkeley DB. Im Moment benutze ich eine wirklich alte Version, aber auf den ersten Blick hat sogar die neueste Version (die von der Oracle-Website vertrieben wird) keine einzige Methode für eine solche Operation.Vergleichen und wechseln Sie in Berkeley DB JE?

Ich war für eine eine Art von Verfahren, die wie

replace(Transaction, Key, ExpectedValue, NewValue) 

mit folgenden Semantik: DB-Wert wird mit einem bestimmten Schlüssel zugeordnet ist, wenn dieser Wert vorhanden und es ist gleich dieser Wert auf ExpectedValue dann wird zu NewValue geändert, andernfalls gibt die Methode den nicht erfolgreichen OperationStatus zurück.

Sieht so aus, als gäbe es keine Methode, also frage ich mich, wie dies auf die effizienteste Art und Weise geschehen soll.

Im Moment bin ich mit den folgenden Ansatz: Ich mache

db.get(null, key) -> {currentValue, version} 
db.put(null, key, {currentValue, newRandomIdVersion}) 
db.get(null, key) 

I Vergleichswert und Version, wenn sie übereinstimmen ich letzte Update alte Version löschen. Wenn ein Schritt fehlschlägt, wird der gesamte Prozess neu gestartet.

Ich fühle, dass dies sehr suboptimal ist - liege ich falsch?

+0

Haben Sie etwas versucht? –

+0

Versuchen Sie als ersten Crack, eine Transaktion zu verwenden, und prüfen Sie, ob die Leistung im Maßstab ausreichend ist. –

+0

Meinen Sie nur Zähler innerhalb der Transaktion aktualisieren? Es würde nicht helfen - gleichzeitige Transaktionen überschreiben sich selbst. – Alex

Antwort

0

Meine Lösung in Update zu meiner Frage ist falsch - jedoch ist nur geringfügige Änderung erforderlich, um es besser zu machen.

Die Lösung könnte wie folgt aussehen: Erstellen Sie separate DB für die Speicherung von Sperren, die Verknüpfungen von Schlüsseln zu einem bestimmten Zähler enthalten. Diese Datenbank sollte sortierte Duplikate zulassen (damit Database.get den kleinsten Wert zurückgibt, der einem bestimmten Schlüssel zugeordnet ist). Verwenden Sie dann einen gemeinsam monoton steigenden Zähler. Mehrere Threads, die versuchen, CAS auszuführen, erhalten Werte von diesem Zähler und speichern Schlüssel-Wert-Paare in dieser Sperr-DB. Thread, der den niedrigsten mit einem Schlüssel verknüpften Wert speichert, nimmt an, dass er Schreibberechtigung hat und geht mit dem Vergleich und dem Austausch für den gewünschten Datensatz vor, löscht dann seinen Eintrag aus der Sperrdatenbank, andere Threads versuchen es einfach erneut.