Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Deteksi dan resolusi konflik di AWS AppSync
Saat penulisan bersamaan terjadi AWS AppSync, Anda dapat mengonfigurasi strategi Deteksi Konflik dan Resolusi Konflik untuk menangani pembaruan dengan tepat. Deteksi Konflik menentukan apakah mutasi bertentangan dengan item tertulis yang sebenarnya di sumber data. Deteksi Konflik diaktifkan dengan menyetel nilai SyncConfig di conflictDetection
bidang untukVERSION
.
Resolusi Konflik adalah tindakan yang diambil jika konflik terdeteksi. Ini ditentukan dengan mengatur bidang Conflict Handler di. SyncConfig Ada tiga strategi Resolusi Konflik:
-
OPTIMISTIC_CONCURRENCY
-
AUTOMERGE
-
LAMBDA
Versi secara otomatis bertambah AWS AppSync selama operasi penulisan dan tidak boleh dimodifikasi oleh klien atau di luar resolver yang dikonfigurasi dengan sumber data berkemampuan versi. Melakukan hal itu akan mengubah perilaku konsistensi sistem dan dapat mengakibatkan hilangnya data.
Konkurensi optimis
Optimistic Concurrency adalah strategi resolusi konflik yang AWS AppSync menyediakan sumber data berversi. Ketika penyelesai konflik disetel ke Optimistic Concurrency, jika mutasi yang masuk terdeteksi memiliki versi yang berbeda dari versi objek yang sebenarnya, penangan konflik hanya akan menolak permintaan yang masuk. Di dalam respons GraphQL, item yang ada di server yang memiliki versi terbaru akan disediakan. Klien kemudian diharapkan untuk menangani konflik ini secara lokal dan mencoba lagi mutasi dengan versi item yang diperbarui.
Automerges
Automerge memberi pengembang cara mudah untuk mengonfigurasi strategi resolusi konflik tanpa menulis logika sisi klien untuk menggabungkan konflik secara manual yang tidak dapat ditangani oleh strategi lain. Automerge mematuhi aturan ketat yang ditetapkan saat menggabungkan data untuk menyelesaikan konflik. Prinsip Automerge berkisar pada tipe data yang mendasari bidang GraphQL. Mereka adalah sebagai berikut:
-
Konflik pada bidang skalar: skalar GraphQL atau bidang apa pun yang bukan koleksi (yaitu Daftar, Set, Peta). Tolak nilai masuk untuk bidang skalar dan pilih nilai yang ada di server.
-
Konflik dalam daftar: Jenis GraphQL dan tipe database adalah daftar. Gabungkan daftar masuk dengan daftar yang ada di server. Nilai daftar dalam mutasi yang masuk akan ditambahkan ke akhir daftar di server. Nilai duplikat akan dipertahankan.
-
Konflik pada satu set: Jenis GraphQL adalah daftar dan tipe database adalah Set. Terapkan gabungan set menggunakan set masuk dan set yang ada di server. Ini melekat pada properti Set, yang berarti tidak ada entri duplikat.
-
Ketika mutasi yang masuk menambahkan bidang baru ke item atau dibuat terhadap bidang dengan nilai
null
, gabungkan itu ke item yang ada. -
Konflik pada peta: Ketika tipe data yang mendasari dalam database adalah Peta (yaitu dokumen nilai kunci), terapkan aturan di atas saat mem-parsing dan memproses setiap properti Peta.
Automerge dirancang untuk secara otomatis mendeteksi, menggabungkan, dan mencoba ulang permintaan dengan versi yang diperbarui, membebaskan klien dari kebutuhan untuk menggabungkan data yang bertentangan secara manual.
Untuk menunjukkan contoh bagaimana Automerge menangani Konflik pada tipe Skalar. Kami akan menggunakan catatan berikut sebagai titik awal kami.
{ "id" : 1, "name" : "Nadia", "jersey" : 5, "_version" : 4 }
Sekarang mutasi yang masuk mungkin mencoba memperbarui item tetapi dengan versi yang lebih lama karena klien belum disinkronkan dengan server. Itu terlihat seperti ini:
{ "id" : 1, "name" : "Nadia", "jersey" : 55, "_version" : 2 }
Perhatikan versi 2 yang sudah ketinggalan zaman dalam permintaan yang masuk. Selama alur ini, Automerge akan menggabungkan data dengan menolak pembaruan bidang 'jersey' ke '55' dan mempertahankan nilainya pada '5' sehingga gambar item berikut disimpan di server.
{ "id" : 1, "name" : "Nadia", "jersey" : 5, "_version" : 5 # version is incremented every time automerge performs a merge that is stored on the server. }
Mengingat status item yang ditunjukkan di atas pada versi 5, sekarang anggaplah mutasi masuk yang mencoba mengubah item dengan gambar berikut:
{ "id" : 1, "name" : "Shaggy", "jersey" : 5, "interests" : ["breakfast", "lunch", "dinner"] # underlying data type is a Set "points": [24, 30, 27] # underlying data type is a List "_version" : 3 }
Ada tiga hal menarik dalam mutasi yang masuk. Nama, skalar, telah diubah tetapi dua bidang baru “kepentingan”, Set, dan “poin”, Daftar, telah ditambahkan. Dalam skenario ini, konflik akan terdeteksi karena ketidakcocokan versi. Automerge mematuhi propertinya dan menolak perubahan nama karena menjadi skalar dan menambahkan bidang yang tidak bertentangan. Ini menghasilkan item yang disimpan di server untuk muncul sebagai berikut.
{ "id" : 1, "name" : "Nadia", "jersey" : 5, "interests" : ["breakfast", "lunch", "dinner"] # underlying data type is a Set "points": [24, 30, 27] # underlying data type is a List "_version" : 6 }
Dengan gambar item yang diperbarui dengan versi 6, sekarang anggaplah mutasi yang masuk (dengan ketidakcocokan versi lain) mencoba mengubah item menjadi berikut:
{ "id" : 1, "name" : "Nadia", "jersey" : 5, "interests" : ["breakfast", "lunch", "brunch"] # underlying data type is a Set "points": [30, 35] # underlying data type is a List "_version" : 5 }
Di sini kita mengamati bahwa bidang masuk untuk “kepentingan” memiliki satu nilai duplikat yang ada di server dan dua nilai baru. Dalam hal ini, karena tipe data yang mendasarinya adalah Set, Automerge akan menggabungkan nilai yang ada di server dengan yang ada di permintaan masuk dan menghapus duplikat apa pun. Demikian pula ada konflik pada bidang “poin” di mana ada satu nilai duplikat dan satu nilai baru. Tetapi karena tipe data yang mendasari di sini adalah Daftar, Automerge hanya akan menambahkan semua nilai dalam permintaan masuk ke akhir nilai yang sudah ada di server. Gambar gabungan yang dihasilkan disimpan di server akan muncul sebagai berikut:
{ "id" : 1, "name" : "Nadia", "jersey" : 5, "interests" : ["breakfast", "lunch", "dinner", "brunch"] # underlying data type is a Set "points": [24, 30, 27, 30, 35] # underlying data type is a List "_version" : 7 }
Sekarang mari kita asumsikan item yang disimpan di server muncul sebagai berikut, pada versi 8.
{ "id" : 1, "name" : "Nadia", "jersey" : 5, "interests" : ["breakfast", "lunch", "dinner", "brunch"] # underlying data type is a Set "points": [24, 30, 27, 30, 35] # underlying data type is a List "stats": { "ppg": "35.4", "apg": "6.3" } "_version" : 8 }
Tetapi permintaan yang masuk mencoba memperbarui item dengan gambar berikut, sekali lagi dengan ketidakcocokan versi:
{ "id" : 1, "name" : "Nadia", "stats": { "ppg": "25.7", "rpg": "6.9" } "_version" : 3 }
Sekarang dalam skenario ini, kita dapat melihat bahwa bidang yang sudah ada di server hilang (minat, poin, jersey). Selain itu, nilai untuk “ppg” dalam peta “statistik” sedang diedit, nilai baru “rpg” ditambahkan, dan “apg” dihilangkan. Automerge mempertahankan bidang yang telah dihilangkan (catatan: jika bidang dimaksudkan untuk dihapus, maka permintaan harus dicoba lagi dengan versi yang cocok), sehingga tidak akan hilang. Ini juga akan menerapkan aturan yang sama ke bidang dalam peta dan oleh karena itu perubahan ke “ppg” akan ditolak sedangkan “apg” dipertahankan dan “rpg”, bidang baru”, ditambahkan pada. Item yang dihasilkan disimpan di server sekarang akan muncul sebagai:
{ "id" : 1, "name" : "Nadia", "jersey" : 5, "interests" : ["breakfast", "lunch", "dinner", "brunch"] # underlying data type is a Set "points": [24, 30, 27, 30, 35] # underlying data type is a List "stats": { "ppg": "35.4", "apg": "6.3", "rpg": "6.9" } "_version" : 9 }
Lambda
Ada beberapa strategi resolusi Lambda untuk dipilih:
-
RESOLVE
: Mengganti item yang ada dengan item baru yang disediakan dalam muatan respons. Anda hanya dapat mencoba lagi operasi yang sama pada satu item pada satu waktu. Saat ini didukung untuk DynamoDB &PutItem
.UpdateItem
-
REJECT
: Menolak mutasi dan mengembalikan kesalahan dengan item yang ada dalam respons GraphQL. Saat ini didukung untuk DynamoDB,,PutItem
&UpdateItem
.DeleteItem
-
REMOVE
: Menghapus item yang ada. Saat ini didukung untuk DynamoDBDeleteItem
.
Permintaan Doa Lambda
Penyelesai AWS AppSync DynamoDB memanggil fungsi Lambda yang ditentukan dalam. LambdaConflictHandlerArn
Ini menggunakan service-role-arn
konfigurasi yang sama pada sumber data. Muatan doa memiliki struktur sebagai berikut:
{ "newItem": { ... }, "existingItem": {... }, "arguments": { ... }, "resolver": { ... }, "identity": { ... } }
Bidang didefinisikan sebagai berikut:
-
newItem
-
Item pratinjau, jika mutasi berhasil.
-
existingItem
-
Item saat ini berada di tabel DynamoDB.
-
arguments
-
Argumen dari mutasi GraphQL.
-
resolver
-
Informasi tentang AWS AppSync resolver.
-
identity
-
Informasi tentang penelepon. Bidang ini diatur ke null, jika akses dengan API kunci.
Contoh payload:
{ "newItem": { "id": "1", "author": "Jeff", "title": "Foo Bar", "rating": 5, "comments": ["hello world"], }, "existingItem": { "id": "1", "author": "Foo", "rating": 5, "comments": ["old comment"] }, "arguments": { "id": "1", "author": "Jeff", "title": "Foo Bar", "comments": ["hello world"] }, "resolver": { "tableName": "post-table", "awsRegion": "us-west-2", "parentType": "Mutation", "field": "updatePost" }, "identity": { "accountId": "123456789012", "sourceIp": "x.x.x.x", "username": "AIDAAAAAAAAAAAAAAAAAA", "userArn": "arn:aws:iam::123456789012:user/appsync" } }
Tanggapan Doa Lambda
Untuk PutItem
dan resolusi UpdateItem
konflik
RESOLVE
mutasi. Responsnya harus dalam format berikut.
{ "action": "RESOLVE", "item": { ... } }
item
Bidang mewakili objek yang akan digunakan untuk mengganti item yang ada di sumber data yang mendasarinya. Kunci utama dan metadata sinkronisasi akan diabaikan jika disertakan dalam. item
REJECT
mutasi. Responsnya harus dalam format berikut.
{ "action": "REJECT" }
Untuk resolusi DeleteItem
konflik
REMOVE
item. Responsnya harus dalam format berikut.
{ "action": "REMOVE" }
REJECT
mutasi. Responsnya harus dalam format berikut.
{ "action": "REJECT" }
Contoh fungsi Lambda di bawah ini memeriksa siapa yang membuat panggilan dan nama resolver. Jika dibuat olehjeffTheAdmin
, REMOVE
objek untuk DeletePost resolver atau konflik dengan item baru untuk RESOLVE
Update/Put resolvers. Jika tidak, mutasinyaREJECT
.
exports.handler = async (event, context, callback) => { console.log("Event: "+ JSON.stringify(event)); // Business logic goes here. var response; if ( event.identity.user == "jeffTheAdmin" ) { let resolver = event.resolver.field; switch(resolver) { case "deletePost": response = { "action" : "REMOVE" } break; case "updatePost": case "createPost": response = { "action" : "RESOLVE", "item": event.newItem } break; default: response = { "action" : "REJECT" }; } } else { response = { "action" : "REJECT" }; } console.log("Response: "+ JSON.stringify(response)); return response; }
Kesalahan
Di bawah ini adalah daftar kemungkinan kesalahan yang mungkin terjadi selama proses Resolusi Konflik:
-
ConflictUnhandled
-
Deteksi konflik menemukan ketidakcocokan versi dan penangan konflik menolak mutasi.
Contoh: Resolusi konflik dengan penangan konflik Konkurensi Optimis. Atau, penangan konflik Lambda kembali dengan.
REJECT
-
ConflictError
-
Kesalahan internal terjadi ketika mencoba menyelesaikan konflik.
Contoh: Penangan konflik Lambda mengembalikan respons yang salah bentuk. Atau, tidak dapat memanggil penangan konflik Lambda karena
LambdaConflictHandlerArn
sumber daya yang disediakan tidak ditemukan. -
MaxConflicts
-
Upaya percobaan ulang maksimum dicapai untuk resolusi konflik.
Contoh: Terlalu banyak permintaan bersamaan pada objek yang sama. Sebelum konflik diselesaikan, objek diperbarui ke versi baru oleh klien lain.
-
BadRequest
-
Klien mencoba memperbarui bidang metadata (
_version
,,_ttl
_lastChangedAt
,_deleted
).Contoh: Klien mencoba memperbarui
_version
objek dengan mutasi pembaruan. -
DeltaSyncWriteError
-
Gagal menulis catatan sinkronisasi delta.
Contoh: Mutasi berhasil, tetapi terjadi kesalahan internal saat mencoba menulis ke tabel sinkronisasi delta.
-
InternalFailure
-
Terjadi kesalahan internal.
UnsupportedOperation
-
Operasi yang tidak didukung '
X
'. Pembuatan Versi Sumber Data hanya mendukung operasi berikut (,,, Pindai, KueriTransactGetItems,PutItem,BatchGetItem,, SinkronisasiGetItem). DeleteItem UpdateItemContoh: Menggunakan transaksi dan operasi batch tertentu dengan deteksi/resolusi konflik diaktifkan. Operasi ini saat ini tidak didukung.
CloudWatch Log
Jika AWS AppSync API telah mengaktifkan CloudWatch Log dengan pengaturan logging disetel ke Log Tingkat Bidang enabled
dan tingkat log untuk Log Tingkat Bidang yang disetelALL
, maka AWS AppSync akan memancarkan informasi Deteksi Konflik dan Resolusi ke grup log. Untuk informasi tentang format pesan log, lihat dokumentasi untuk Deteksi Konflik dan Pencatatan Sinkronisasi.