

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Contoh semantik transaksi Neptunus
<a name="transactions-examples"></a>

Contoh berikut menggambarkan kasus penggunaan yang berbeda untuk semantik transaksi di Amazon Neptune.

**Topics**
+ [Penyisipan Bersyarat dari Properti](#transactions-examples-conditional-insertion)
+ [Keunikan Nilai Properti](#transactions-examples-unique-property)
+ [Perubahan Properti Bersyarat](#transactions-examples-conditional-edit)
+ [Mengganti Properti](#transactions-examples-replace)
+ [Menghindari Elemen Menggantung](#transactions-examples-dangling)

## Contoh 1 - Memasukkan Properti Hanya Jika Tidak Ada
<a name="transactions-examples-conditional-insertion"></a>

Misalkan Anda ingin memastikan bahwa properti diatur hanya sekali. Sebagai contoh, misalkan beberapa kueri mencoba untuk menetapkan kepada seseorang skor kredit secara bersamaan. Anda hanya ingin satu instans dari properti dimasukkan, dan kueri lainnya gagal karena properti telah ditetapkan.

```
# GREMLIN:
g.V('person1').hasLabel('Person').coalesce(has('creditScore'), property('creditScore', 'AAA+'))

# SPARQL:
INSERT { :person1 :creditScore "AAA+" .}
WHERE  { :person1 rdf:type :Person .
         FILTER NOT EXISTS { :person1 :creditScore ?o .} }
```

Langkah `property()` Gremlin menyisipkan properti dengan kunci dan nilai yang diberikan. Langkah `coalesce()` mengeksekusi argumen pertama di langkah pertama, dan jika gagal, maka mengeksekusi langkah kedua:

Sebelum memasukkan nilai properti `creditScore` untuk vertex `person1` yang diberikan, transaksi harus coba membaca kemungkinan tidak adanya nilai `creditScore` untuk `person1`. Ini mencoba membaca kunci rentang `SP` untuk `S=person1` dan `P=creditScore` dalam `SPOG` indeks tempat nilai `creditScore` ada atau akan ditulis.

Mengambil kunci rentang ini mencegah transaksi bersamaan apapun dari memasukkan nilai `creditScore` secara bersamaan. Ketika ada beberapa transaksi paralel, paling banyak salah satu dari transaksi tersebut dapat memperbarui nilai pada suatu waktu. Ini mengeliminasi anomali lebih dari satu properti `creditScore` yang dibuat.

## Contoh 2 - Menegaskan Bahwa Nilai Properti Adalah Unik secara Global
<a name="transactions-examples-unique-property"></a>

Misalkan Anda ingin memasukkan seseorang dengan nomor Jaminan Sosial sebagai kunci utama. Anda ingin kueri mutasi Anda menjamin bahwa, pada tingkat global, tidak ada orang lain dalam database memiliki nomor Jaminan Sosial yang sama:

```
# GREMLIN:
g.V().has('ssn', 123456789).fold()
  .coalesce(__.unfold(),
            __.addV('Person').property('name', 'John Doe').property('ssn', 123456789'))

# SPARQL:
INSERT { :person1 rdf:type :Person .
         :person1 :name "John Doe" .
         :person1 :ssn 123456789 .}
WHERE  { FILTER NOT EXISTS { ?person :ssn 123456789 } }
```

Contoh ini sama dengan yang sebelumnya. Perbedaan utamanya adalah bahwa kunci rentang diambil pada indeks `POGS` ketimbang indeks `SPOG`.

Transaksi mengeksekusi kueri harus membaca pola, `?person :ssn 123456789`, di mana posisi `P` dan `O` terikat. Kunci rentang diambil pada indeks `POGS` untuk `P=ssn` dan `O=123456789`.
+ Jika pola itu ada, tidak ada tindakan yang diambil.
+ Jika tidak ada, penguncian mencegah setiap transaksi bersamaan dari menyisipkan nomor Jaminan Sosial juga

## Contoh 3 - Mengubah Properti Jika Properti Lain Memiliki Nilai Tertentu
<a name="transactions-examples-conditional-edit"></a>

Misalkan berbagai peristiwa dalam game memindahkan seseorang dari tingkat satu ke tingkat dua, dan menugaskan mereka properti `level2Score` baru yang diatur ke nol. Anda harus yakin bahwa beberapa instans yang bersamaan dari transaksi tersebut tidak dapat membuat beberapa instans dari properti skor tingkat-dua. Kueri di Gremlin dan SPARQL mungkin terlihat seperti berikut ini.

```
# GREMLIN:
g.V('person1').hasLabel('Person').has('level', 1)
 .property('level2Score', 0)
 .property(Cardinality.single, 'level', 2)

# SPARQL:
DELETE { :person1 :level 1 .}
INSERT { :person1 :level2Score 0 .
         :person1 :level 2 .}
WHERE  { :person1 rdf:type :Person .
         :person1 :level 1 .}
```

Di Gremlin, ketika `Cardinality.single` ditentukan, langkah `property()` menambahkan properti baru atau menggantikan nilai properti yang ada dengan nilai baru yang ditentukan.

Setiap pembaruan ke nilai properti, seperti meningkatkan `level` dari 1 sampai 2, diimplementasikan sebagai penghapusan catatan saat ini dan penyisipan catatan baru dengan nilai properti baru. Dalam hal ini, catatan dengan tingkat nomor 1 dihapus dan catatan dengan tingkat nomor 2 dimasukkan kembali.

Untuk transaksi agar dapat menambah `level2Score` dan memperbarui `level` dari 1 sampai 2, transaksi harus terlebih dahulu memvalidasi bahwa nilai `level` saat ini sama dengan 1. Dengan demikian, dibutuhkan kunci rentang pada prefiks `SPO` untuk `S=person1`, `P=level`, dan `O=1` dalam indeks `SPOG`. Kunci ini mencegah transaksi yang bersamaan menghapus versi 1 tiga kali lipat, dan sebagai hasilnya, tidak ada pembaruan bersamaan yang bertentangan dapat terjadi.

## Contoh 4 - Mengganti Properti yang Ada
<a name="transactions-examples-replace"></a>

Peristiwa tertentu dapat memperbarui nilai kredit seseorang ke nilai baru (di sini `BBB`). Tetapi Anda ingin memastikan bahwa peristiwa bersamaan dari jenis tersebut tidak dapat membuat beberapa properti skor kredit untuk seseorang.

```
# GREMLIN:
g.V('person1').hasLabel('Person')
 .sideEffect(properties('creditScore').drop())
 .property('creditScore', 'BBB')

# SPARQL:
DELETE { :person1 :creditScore ?o .}
INSERT { :person1 :creditScore "BBB" .}
WHERE  { :person1 rdf:type :Person .
         :person1 :creditScore ?o .}
```

Kasus ini mirip dengan contoh 3, kecuali bahwa alih-alih mengunci `SPO` awalan, Neptunus mengunci `SP` awalan dengan dan hanya. `S=person1` `P=creditScore` Hal ini mencegah transaksi bersamaan dari memasukkan atau menghapus setiap triple dengan properti `creditScore` untuk subjek `person1`.

## Contoh 5 - Menghindari Properti atau Edge Menggantung
<a name="transactions-examples-dangling"></a>

Pembaruan pada entitas tidak harus meninggalkan elemen menggantung, yaitu properti atau edge yang terkait dengan entitas yang tidak diketik. Ini hanya masalah di SPARQL, karena Gremlin memiliki kendala built-in untuk mencegah elemen menggantung .

```
# SPARQL:
tx1: INSERT { :person1 :age 23 } WHERE { :person1 rdf:type :Person }
tx2: DELETE { :person1 ?p ?o }
```

Kueri `INSERT` harus membaca dan mengunci prefiks `SPO` dengan `S=person1`, `P=rdf:type`, dan `O=Person` dalam indeks `SPOG`. Penguncian mencegah kueri `DELETE` dari berhasilnya secara paralel.

Dalam perlombaan antara query `DELETE` mencoba untuk menghapus rekaman `:person1 rdf:type :Person` dan query `INSERT` membaca catatan dan membuat kunci rentang di `SPO` dalam Indeks `SPOG`, hasil berikut ini mungkin:
+ Jika kueri `INSERT` melakukan sebelum kueri `DELETE` membaca dan menghapus semua catatan untuk `:person1`, `:person1` dihapus seluruhnya dari database, termasuk catatan yang baru dimasukkan.
+ Jika query `DELETE` melakukan sebelum kueri `INSERT` coba membaca catatan `:person1 rdf:type :Person`, pembacaan mengamati perubahan yang dilakukan. Artinya, tidak menemukan catatan `:person1 rdf:type :Person` apapun dan karenanya menjadi no-op.
+ Jika query `INSERT` membaca sebelum query `DELETE`, triple `:person1 rdf:type :Person` terkunci dan kueri `DELETE` diblokir sampai kueri INSERT dilakukan, seperti dalam kasus pertama sebelumnya.
+ Jika bacaan `DELETE` membaca sebelum kueri `INSERT`, dan kueri `INSERT` mencoba untuk membaca dan mengunci prefiks `SPO` untuk catatan, maka konflik terdeteksi. Hal ini karena triple telah ditandai untuk dihapus, dan `INSERT` kemudian gagal.

Dalam semua urutan kemungkinan yang berbeda dari peristiwa ini, tidak ada edge menggantung dibuat.