

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.

# Transaktionsisolierungsstufen in Neptune
<a name="transactions-neptune"></a>

Amazon Neptune implementiert unterschiedliche Transaktionsisolationsstufen für schreibgeschützte Abfragen und Mutationsabfragen. SPARQL- und Gremlin-Abfragen werden basierend auf den folgenden Kriterien als schreibgeschützte oder als Mutationsabfragen klassifiziert:
+ In SPARQL gibt es einen deutlichen Unterschied zwischen Lesevorgängen (`SELECT`, `ASK`, `CONSTRUCT` und `DESCRIBE` wie in der [SPARQL 1.1 Query Language](https://www.w3.org/TR/sparql11-query/)-Spezifikation definiert) und Mutationsabfragen (`INSERT` und `DELETE` wie in der [SPARQL 1.1 Update](https://www.w3.org/TR/sparql11-update/)-Spezifikation definiert).

  Beachten Sie, dass Neptune mehrere Mutationsabfragen, die zusammen gesendet werden (z. B. in einer `POST`-Nachricht, getrennt durch Semikolon), als eine einzige Transaktion behandelt. Sie sind gemeinsam entweder erfolgreich oder nicht erfolgreich. Wenn sie nicht erfolgreich sind, werden teilweise Änderungen zurückgesetzt.
+ In Gremlin klassifiziert Neptune eine Abfrage jedoch als schreibgeschützte Abfrage oder als Mutationsabfrage, abhängig davon, ob sie Abfragepfadschritte wie `addE()`, `addV()`, `property()` oder `drop()` enthält, die Daten manipulieren. Wenn die Abfrage einen solchen Pfadschritt enthält, wird sie als Mutationsabfrage klassifiziert und ausgeführt.

Es ist auch möglich, stehende Sitzungen in Gremlin zu verwenden. Weitere Informationen finden Sie unter [Skriptbasierte Gremlin-Sitzungen](access-graph-gremlin-sessions.md). In diesen Sitzungen werden alle Abfragen (einschließlich schreibgeschützter Abfragen) mit derselben Isolierung wie Mutationsabfragen auf dem Writer-Endpunkt ausgeführt.

Bei Verwendung von Bolt-Lese-Schreib-Vorgängen in openCypher werden alle Abfragen (einschließlich schreibgeschützter Abfragen) mit derselben Isolierung wie Mutationsabfragen auf dem Writer-Endpunkt ausgeführt. 

**Topics**
+ [Isolation schreibgeschützter Abfragen in Neptune](#transactions-neptune-read-only)
+ [Isolierung von Mutationsabfragen in Neptune](#transactions-neptune-mutation)
+ [Konfliktlösung mithilfe von Sperrwartezeitüberschreitungen](#transactions-neptune-conflicts)
+ [Bereichssperren und falsche Konflikte](#transactions-neptune-false-conflicts)

## Isolation schreibgeschützter Abfragen in Neptune
<a name="transactions-neptune-read-only"></a>

Neptune evaluiert schreibgeschützte Abfragen gemäß der Snapshot-Isolationssemantik. Das bedeutet, dass eine schreibgeschützte Abfrage logisch auf einem konsistenten Snapshot der Datenbank ausgeführt wird, wenn die Abfrageevaluierung beginnt. Neptune kann dann garantieren, dass keines der folgenden Phänomene eintritt:
+ `Dirty reads` – Schreibgeschützten Abfragen in Neptune werden niemals Daten ohne Commit aus einer gleichzeitigen Transaktion angezeigt.
+ `Non-repeatable reads` – Eine schreibgeschützte Transaktion, die dieselben Daten mehrmals liest, erhält stets dieselben Werte zurück.
+ `Phantom reads` – Eine schreibgeschützte Transaktion liest niemals Daten, die nach Beginn der Transaktion hinzugefügt wurden.

Da die Snapshot-Isolierung durch Multiversion Concurrency Control (MVCC) erzielt wird, müssen schreibgeschützte Abfragen keine Daten sperren und blockieren daher keine Mutationsabfragen.

Read Replicas akzeptieren nur schreibgeschützte Abfragen, sodass alle Abfragen für Read Replicas gemäß der `SNAPSHOT`-Isolationssemantik ausgeführt werden.

Der einzige zusätzliche Aspekt bei der Abfrage einer Read Replica besteht darin, dass es eine kleine Verzögerung bei der Replikation zwischen dem Writer und den Read Replicas geben kann. Dies bedeutet, dass eine Aktualisierung, die am Writer vorgenommen wurde, einige Zeit in Anspruch nehmen kann, bis sie auf die Read Replica übertragen wird, aus der Sie lesen. Die tatsächliche Replikationszeit ist von der Schreiblast der primären Instance abhängig. Die Neptune-Architektur unterstützt die Replikation mit niedriger Latenz, und die Replikationsverzögerung wird in einer Amazon-Metrik instrumentiert. CloudWatch 

Aufgrund der `SNAPSHOT`-Isolationsstufe wird Leseabfragen stets ein konsistenter Zustand der Datenbank angezeigt, auch wenn es sich nicht um den neuesten Zustand handelt.

Wenn Sie eine starke Garantie benötigen, dass eine Abfrage das Ergebnis einer vorherigen Aktualisierung beachtet, senden Sie die Abfrage an den Writer-Endpunkt selbst und nicht an eine Read Replica.

## Isolierung von Mutationsabfragen in Neptune
<a name="transactions-neptune-mutation"></a>

Als Teil von Mutationsabfragen erstellte Lesevorgänge werden unter `READ COMMITTED`-Transaktionsisolierung ausgeführt, was die Möglichkeit von fehlerhaften Lesevorgängen ausschließt. Abgesehen von den üblichen Garantien für die `READ COMMITTED`-Transaktionsisolierung bietet Neptune eine starke Garantie, dass weder `PHANTOM`- noch `NON-REPEATABLE`- Lesevorgänge erfolgen können.

Diese starken Garantien werden erreicht, indem Datensätze und Bereiche von Datensätzen beim Lesen von Daten gesperrt werden. Dadurch wird verhindert, dass gleichzeitige Transaktionen Einfügungen oder Löschungen in Indexbereichen vornehmen, nachdem sie gelesen wurden, was wiederholbare Lesevorgänge garantiert.

**Anmerkung**  
Eine gleichzeitige Mutationstransaktion `Tx2` könnte jedoch nach dem Start der Mutationstransaktion `Tx1` beginnen und das Commit einer Änderung durchführen, bevor `Tx1` Daten zum Lesen gesperrt hatte. In diesem Fall würde `Tx1` die Änderung von `Tx2` so sehen, als ob `Tx2` sie vor dem Start von `Tx1` abgeschlossen hätte. Da dies nur für Änderungen gilt, für die ein Commit durchgeführt wurde, kann ein `dirty read` nie auftreten.

Um den Sperrmechanismus zu verstehen, den Neptune für Mutationsabfragen verwendet, sollten zunächst die Details für das [Diagrammdatenmodell](feature-overview-data-model.md) und die [Indizierungsstrategie](feature-overview-storage-indexing.md) in Neptune verstanden werden. Neptune verwaltet Daten mithilfe von drei Indizes, `SPOG`, `POGS` und `GPSO`.

Um wiederholbare Lesevorgänge für die `READ COMMITTED`-Transaktionsebene zu erzielen, nutzt Neptune Bereichssperren im verwendeten Index. Wenn beispielsweise eine Mutationsabfrage alle Eigenschaften und ausgehenden Grenzen eines Eckpunkts mit dem Namen `person1` liest, würde der Knoten den gesamten durch das Präfix `S=person1` im `SPOG`- Index definierten Bereich sperren, bevor die Daten gelesen werden.

Derselbe Mechanismus gilt bei der Verwendung anderer Indizes. Wenn beispielsweise eine Mutationstransaktion alle Quell-Ziel-Eckpunktpaare für eine bestimmte Grenzbezeichnung mit dem `POGS`-Index absucht, wäre der Bereich für die Grenzbezeichnung in der `P`-Position gesperrt. Jede gleichzeitige Transaktion, unabhängig davon, ob es sich um eine schreibgeschützte oder eine Mutationsabfrage handelt, könnte dennoch Lesevorgänge innerhalb des gesperrten Bereichs durchführen. Jede Mutation, die das Einfügen oder Löschen neuer Datensätze im gesperrten Präfixbereich beinhaltet, erfordert jedoch eine exklusive Sperre und würde verhindert werden.

Anders gesagt: Wenn ein Bereich des Indexes von einer Mutationstransaktion gelesen wurde, gibt es eine starke Garantie, dass dieser Bereich bis zum Ende der Lesetransaktion nicht durch gleichzeitige Transaktionen geändert wird. Auf diese Weise wird sichergestellt, dass kein `non-repeatable reads` auftritt.

## Konfliktlösung mithilfe von Sperrwartezeitüberschreitungen
<a name="transactions-neptune-conflicts"></a>

Wenn eine zweite Transaktion versucht, einen Datensatz in einem Bereich zu ändern, den eine erste Transaktion gesperrt hat, erkennt Neptune den Konflikt sofort und blockiert die zweite Transaktion.

Wenn keine Abhängigkeitssperre erkannt wird, wendet Neptune automatisch eine Sperrwartezeitüberschreitung an, bei dem die blockierte Transaktion bis zu 60 Sekunden wartet, bis die sperrende Transaktion abgeschlossen ist und die Sperre aufgehoben wurde.
+ Wenn die Sperrwartezeit abläuft, bevor die Sperre aufgehoben wird, wird die blockierte Transaktion rückabgewickelt.
+ Wenn die Sperre innerhalb des Sperrwartezeitraums aufgehoben wird, wird die zweite Transaktion entsperrt und kann erfolgreich abgeschlossen werden, ohne dass ein erneuter Versuch erfolgen muss.

Wenn Neptune jedoch eine Abhängigkeitssperre zwischen den beiden Transaktionen erkennt, ist eine automatische Beseitigung des Konflikts nicht möglich. In diesem Fall bricht Neptune eine der beiden Transaktionen sofort ab und führt ein Rollback für diese Transaktion aus, ohne eine Sperrwartezeitüberschreitung zu initiieren. Neptune versucht dabei, die Transaktion rückgängig zu machen, in der die wenigsten Datensätze eingefügt oder gelöscht wurden.

### Messung der Wartezeit bei Sperre (Engine ≥ 1.4.5.0)
<a name="transactions-neptune-lock-wait-metrics"></a>

Ab Engine-Version 1.4.5.0 können Sie anhand von zwei Zählern genau beobachten, wie lange eine Mutationsabfrage blockiert wurde: slow-query-log


| Zähler | Description | 
| --- | --- | 
| `sharedLocksWaitTimeMillis` | Wartezeit auf gemeinsame Sperren (S), die mehrere Lesegeräte zulassen, aber Schreibvorgänge blockieren. | 
| `exclusiveLocksWaitTimeMillis` | Wartezeit auf exklusive Sperren (X), die jeden anderen Zugriff blockieren. | 

Diese beiden Felder werden im `storageCounters` Objekt nur angezeigt, wenn Sie den `debug` Anmeldemodus für langsame Abfragen aktivieren ()`neptune_enable_slow_query_log=debug`.

**Tipp**  
`sharedLocksWaitTimeMillis + exclusiveLocksWaitTimeMillis`Nähert man sich der Abfrage`overallRunTimeMs`, wird die Abfrage eher durch einen Sperrkonflikt als durch CPU, Netzwerk oder I/O blockiert.

Praktische Tipps zur Reduzierung von Konflikten:
+ **Staffelung widersprüchlicher Jobs** — Führen Sie umfangreiche Batch-Mutationen in Zeiten geringerer Benutzeraktivität durch.
+ **Teilen Sie große Mutationen in kleinere Teile auf — Kleinere** Transaktionen enthalten Sperren für kürzere Zeit, wodurch die Wahrscheinlichkeit von Timeouts verringert wird.

## Bereichssperren und falsche Konflikte
<a name="transactions-neptune-false-conflicts"></a>

Neptune führt Bereichssperren mithilfe von Gap-Sperren aus. Eine Gap-Sperre ist eine Sperre für eine Lücke zwischen Indexdatensätzen oder eine Sperre für eine Lücke vor dem ersten oder nach dem letzten Indexdatensatz.

Neptune verwendet eine sogenannte Verzeichnistabelle, um bestimmten Zeichenkettenliteralen numerische ID-Werte zuzuordnen. Dies ist ein Beispielstatus eines solchen Neptun-Verzeichnisses: Tabelle:


| Zeichenfolge | ID (ID) | 
| --- | --- | 
| type | 1 | 
| default\$1graph | 2 | 
| person\$13 | 3 | 
| person\$11 | 5 | 
| knows | 6 | 
| person\$12 | 7 | 
| age | 8 | 
| edge\$11 | 9 | 
| lives\$1in | 10 | 
| New York | 11 | 
| Person | 12 | 
| Place | 13 | 
| edge\$12 | 14 | 

Die Zeichenfolgen oben gehören zu einem Eigenschaftsdiagrammmodell. Die Konzepte gelten jedoch für alle RDF-Diagrammmodelle.

Der entsprechende Status des SPOG-Index (Subject-Predicate-Object\$1Graph) wird unten links gezeigt. Rechts werden die entsprechenden Zeichenfolgen gezeigt, um die Bedeutung der Indexdaten zu vermitteln.


| S (ID) | P (ID) | O (ID) | G (ID) |  | S (Zeichenfolge) | P (Zeichenfolge) | O (Zeichenfolge) | G (Zeichenfolge) | 
| --- | --- | --- | --- | --- | --- | --- | --- | --- | 
| 3 | 1 | 12 | 2 |  | person\$13 | type | Person | default\$1graph | 
| 5 | 1 | 12 | 2 |  | person\$11 | type | Person | default\$1graph | 
| 5 | 6 | 3 | 9 |  | person\$11 | knows | person\$13 | edge\$11 | 
| 5 | 8 | 40 | 2 |  | person\$11 | age | 40 | default\$1graph | 
| 5 | 10 | 11 | 14 |  | person\$11 | lives\$1in | New York | edge\$12 | 
| 7 | 1 | 12 | 2 |  | person\$12 | type | Person | default\$1graph | 
| 11 | 1 | 13 | 2 |  | New York | type | Place | default\$1graph | 

Wenn beispielsweise eine Mutationsabfrage alle Eigenschaften und ausgehenden Kanten eines Eckpunkts mit dem Namen `person_1` liest, würde der Knoten den gesamten durch das Präfix `S=person_1` im SPOG-Index definierten Bereich sperren, bevor die Daten gelesen werden. Die Bereichssperre würde Gap-Sperren für alle übereinstimmenden Datensätze und den ersten Datensatz einrichten, der nicht übereinstimmt. Übereinstimmende Datensätze würden gesperrt. Nicht übereinstimmende Datensätze würden nicht gesperrt. Neptune würde die Gap-Sperren wie folgt platzieren:
+ ` 5 1 12 2 `*(Lücke 1)*
+ ` 5 6 3 9 `*(Lücke 2)*
+ ` 5 8 40 2 `*(Lücke 3)*
+ ` 5 10 11 14 `*(Lücke 4)*
+ ` 7 1 12 2 `*(Lücke 5)*

Dies sperrt die folgenden Datensätze:
+ ` 5 1 12 2`
+ ` 5 6 3 9`
+ ` 5 8 40 2`
+ ` 5 10 11 14`

In diesem Zustand werden die folgenden Operationen berechtigterweise blockiert:
+ Einfügen einer neuen Eigenschaft oder Kante für `S=person_1`. Eine neue Eigenschaft, die sich von `type` unterscheidet, oder eine neue Kante müsste in Lücke 2, Lücke 3, Lücke 4 oder Lücke 5 eingefügt werden, die alle gesperrt sind.
+ Löschen eines der vorhandenen Datensätze.

Gleichzeitig würden einige gleichzeitige Operationen fälschlicherweise blockiert (was zu falschen Konflikten führen würde):
+ Alle Eigenschaften oder Kanteneinfügungen für `S=person_3` werden blockiert, da sie in Lücke 1 platziert werden müssten.
+ Jede neue Eckpunkteinfügung, der eine ID zwischen 3 und 5 zugewiesen wird, würde blockiert, da sie in Lücke 1 eingefügt werden müsste.
+ Jede neue Eckpunkteinfügung, der eine ID zwischen 5 und 7 zugewiesen wird, würde blockiert, da sie in Lücke 5 eingefügt werden müsste.

Gap-Sperren sind nicht präzise genug, um die Lücke für ein einzelnes bestimmtes Prädikat zu sperren (um z. B. Lücke 5 für Prädikat `S=5` zu sperren).

Die Bereichssperren werden nur in dem Index platziert, in dem der Lesevorgang stattfindet. Im Beispiel oben sind Datensätze nur im SPOG-Index gesperrt, nicht in POGS oder GPSO. [Lesevorgänge für eine Abfrage können in Abhängigkeit von den Zugriffsmustern, die mit dem `explain` APIs (für [Sparql](sparql-explain-examples.md) und für Gremlin) aufgelistet werden können, für alle Indizes durchgeführt werden.](gremlin-explain.md)

**Anmerkung**  
Gap-Sperren können auch als sichere gleichzeitige Aktualisierungen der zugrunde liegenden Indizes verstanden werden, was ebenfalls zu falschen Konflikten führen kann. Diese Gap-Sperren werden unabhängig von der Isolationsstufe oder den von der Transaktion ausgeführten Lesevorgängen platziert.

Falsche Konflikte können nicht nur auftreten, wenn *gleichzeitige* Transaktionen aufgrund von Lückensperren kollidieren, sondern in einigen Fällen auch, wenn eine Transaktion nach einem Fehler erneut versucht wird. Wenn das durch den Fehler ausgelöste Rollback noch nicht abgeschlossen ist und die Sperren, die zuvor auf die Transaktion angewendet wurden, noch nicht vollständig aufgehoben wurden, stößt der erneute Versuch auf einen falschen Konflikt und schlägt fehl.

Bei hoher Auslastung stellen Sie in der Regel fest, dass 3 bis 4 % der Schreibabfragen aufgrund falscher Konflikte fehlschlagen. Für einen externen Client sind diese falschen Konflikte schwer vorherzusagen und sollten mithilfe von [Wiederholungsversuchen](transactions-exceptions.md) behandelt werden.