View a markdown version of this page

Optimistische Sperre mit Versionsnummer - Amazon DynamoDB

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Optimistische Sperre mit Versionsnummer

Optimistisches Sperren ist eine Strategie, die Konflikte schon beim Schreiben erkennt, anstatt sie zu verhindern. Jedes Element enthält ein Versionsattribut, das mit jeder Aktualisierung erhöht wird. Wenn Sie ein Element aktualisieren, fügen Sie einen Bedingungsausdruck hinzu, der überprüft, ob die Versionsnummer mit dem Wert übereinstimmt, den Ihre Anwendung zuletzt gelesen hat. Wenn ein anderer Prozess das Element in der Zwischenzeit geändert hat, schlägt die Bedingung fehl und DynamoDB gibt a zurück. ConditionalCheckFailedException

Wann sollte optimistisches Sperren verwendet werden

Optimistische Verriegelung ist eine gute Wahl, wenn:

  • Möglicherweise aktualisieren mehrere Benutzer oder Prozesse dasselbe Element, Konflikte treten jedoch selten auf.

  • Der erneute Versuch eines fehlgeschlagenen Schreibvorgangs ist für Ihre Anwendung kostengünstig.

  • Sie möchten den Aufwand und die Komplexität der Verwaltung verteilter Sperren vermeiden.

Zu den häufigsten Beispielen gehören Inventaraktualisierungen im E-Commerce, Plattformen für die gemeinsame Bearbeitung und Aufzeichnungen über Finanztransaktionen.

Kompromisse

Versuchen Sie es bei hohem Streit erneut mit dem Overhead

In Umgebungen mit hoher Parallelität steigt die Wahrscheinlichkeit von Konflikten, was zu mehr Wiederholungen und höheren Schreibkosten führen kann

Komplexität der Implementierung

Das Hinzufügen von Versionskontrolle zu Elementen und die Handhabung bedingter Prüfungen erhöhen die Komplexität der Anwendungslogik. Das AWS SDK für Java v2 Enhanced Client bietet integrierte Unterstützung durch die @DynamoDbVersionAttribute Anmerkung, die Versionsnummern automatisch für Sie verwaltet.

Musterdesign

Fügen Sie jedem Element ein Versionsattribut hinzu. Hier ist ein einfacher Schemaentwurf:

  • Partitionsschlüssel — Eine eindeutige Kennung für jedes Element (z. B.ItemId).

  • Attribute:

    • ItemId – der eindeutige Bezeichner für das Element

    • Version – eine Ganzzahl, die die Versionsnummer des Elements darstellt

    • QuantityLeft – der verbleibende Bestand des Elements

Wenn ein Element zum ersten Mal erstellt wird, wird das Attribut Version auf 1 gesetzt. Mit jeder Aktualisierung wird die Versionsnummer um 1 erhöht.

ItemId (Partitionsschlüssel) Version QuantityLeft
Bananen 1 10
Äpfel 1 5
Orangen 1 7

Implementierung

Gehen Sie folgendermaßen vor, um optimistisches Sperren zu implementieren:

  1. Die aktuelle Version des Elements.

    def get_item(item_id): response = table.get_item(Key={'ItemID': item_id}) return response['Item'] item = get_item('Bananas') current_version = item['Version']
  2. Aktualisieren Sie das Element mithilfe eines Bedingungsausdrucks, der die Versionsnummer überprüft.

    def update_item(item_id, qty_bought, current_version): try: response = table.update_item( Key={'ItemID': item_id}, UpdateExpression="SET QuantityLeft = QuantityLeft - :qty, Version = :new_v", ConditionExpression="Version = :expected_v", ExpressionAttributeValues={ ':qty': qty_bought, ':new_v': current_version + 1, ':expected_v': current_version }, ReturnValues="UPDATED_NEW" ) return response except ClientError as e: if e.response['Error']['Code'] == 'ConditionalCheckFailedException': print("Version conflict: another process updated this item.") raise
  3. Behandeln Sie Konflikte, indem Sie es mit einem neuen Lesevorgang erneut versuchen.

    Jeder Wiederholungsversuch erfordert einen weiteren Lesevorgang. Begrenzen Sie daher die Gesamtzahl der Wiederholungen.

    def update_with_retry(item_id, qty_bought, max_retries=3): for attempt in range(max_retries): item = get_item(item_id) try: return update_item(item_id, qty_bought, item['Version']) except ClientError as e: if e.response['Error']['Code'] != 'ConditionalCheckFailedException': raise print(f"Retry {attempt + 1}/{max_retries}") raise Exception("Update failed after maximum retries.")

Für Java-Anwendungen bietet das AWS SDK für Java v2 Enhanced Client integrierte Unterstützung für optimistisches Sperren mithilfe der @DynamoDbVersionAttribute Anmerkung, die die Versionsnummern automatisch für Sie verwaltet.

Weitere Hinweise zu Bedingungsausdrücken finden Sie unterCLI-Beispiel für DynamoDB-Bedingungsausdrücke.