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 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 das Element in der Zwischenzeit von einem anderen Prozess geändert wurde, schlägt die Bedingung fehl und DynamoDB gibt a zurück. ConditionalCheckFailedException

Wann sollte optimistisches Sperren verwendet werden

Optimistisches Sperren eignet sich gut, wenn:

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

  • Ein erneuter Versuch, einen fehlgeschlagenen Schreibvorgang zu wiederholen, 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

Mehraufwand bei hohem Datenkonflikt erneut versuchen

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 Versionskontrollen zu Elementen und die Handhabung bedingter Prüfungen erhöhen die Komplexität der Anwendungslogik. Das AWS SDK for Java v2 Enhanced Client bietet integrierten Support durch die @DynamoDbVersionAttributeAnmerkung, die Versionsnummern automatisch für Sie verwaltet.

Musterdesign

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

  • Partitionsschlüssel — Ein eindeutiger Bezeichner 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 wie folgt 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 erneut mit einem neuen Lesevorgang versuchen.

    Für jeden erneuten Versuch ist ein zusätzlicher Lesevorgang erforderlich. Beschränken 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 for Java v2 Enhanced Client integrierte Unterstützung für optimistisches Sperren über die @DynamoDbVersionAttributeAnmerkung, die Versionsnummern automatisch für Sie verwaltet.

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