Gunakan Tablestore SDK for Go untuk menjalankan transaksi lokal dalam satu nilai kunci partisi sehingga semua operasi tulis dalam transaksi tersebut di-commit atau dibatalkan secara bersamaan. Tingkat isolasi yang digunakan adalah Read Committed.
Prasyarat
-
Instal Tablestore SDK for Go dan inisialisasi klien. Transaksi lokal memerlukan versi 1.7.8 atau lebih baru. Disarankan untuk menggunakan versi terbaru.
-
Transaksi lokal telah diaktifkan untuk tabel tersebut. Anda dapat mengatur
EnableLocalTxnsaat membuat tabel. Untuk memeriksa apakah transaksi lokal sudah diaktifkan pada tabel yang sudah ada atau untuk mengaktifkannya, kirimkan tiket.
Deskripsi
Transaksi lokal dibatasi pada satu nilai kunci partisi. Operasi baca dan tulis dalam transaksi berbagi ID transaksi yang sama. Alur kerja terdiri dari tiga tahap:
-
Panggil
StartLocalTransactiondengan nilai kunci partisi untuk membuat transaksi lokal dan mendapatkan ID transaksinya. -
Panggil
GetRow,PutRow,UpdateRow,DeleteRow,BatchWriteRow, atauGetRangedalam transaksi tersebut dan sertakan ID transaksi pada setiap permintaan. -
Panggil
CommitTransactionuntuk menerapkan semua perubahan atauAbortTransactionuntuk membatalkan transaksi beserta semua perubahannya.
func (client *TableStoreClient) StartLocalTransaction(request *StartLocalTransactionRequest) (*StartLocalTransactionResponse, error)
func (client *TableStoreClient) CommitTransaction(request *CommitTransactionRequest) (*CommitTransactionResponse, error)
func (client *TableStoreClient) AbortTransaction(request *AbortTransactionRequest) (*AbortTransactionResponse, error)
Contoh berikut membuat transaksi lokal untuk nilai kunci partisi user-a, menulis satu baris dalam transaksi tersebut, lalu melakukan commit terhadap transaksi.
partitionKey := &tablestore.PrimaryKey{}
partitionKey.AddPrimaryKeyColumn("user_id", "user-a")
startResponse, err := client.StartLocalTransaction(
&tablestore.StartLocalTransactionRequest{
TableName: "example_table",
PrimaryKey: partitionKey,
},
)
if err != nil {
log.Fatal(err)
}
transactionID := startResponse.TransactionId
rowKey := &tablestore.PrimaryKey{}
rowKey.AddPrimaryKeyColumn("user_id", "user-a")
rowKey.AddPrimaryKeyColumn("record_id", int64(1))
change := &tablestore.PutRowChange{
TableName: "example_table",
PrimaryKey: rowKey,
TransactionId: transactionID,
}
change.AddColumn("status", "created")
change.SetCondition(tablestore.RowExistenceExpectation_IGNORE)
_, err = client.PutRow(&tablestore.PutRowRequest{PutRowChange: change})
if err != nil {
_, _ = client.AbortTransaction(
&tablestore.AbortTransactionRequest{TransactionId: transactionID},
)
log.Fatal(err)
}
_, err = client.CommitTransaction(
&tablestore.CommitTransactionRequest{TransactionId: transactionID},
)
if err != nil {
log.Fatal(err)
}
Parameter
Buat transaksi lokal
StartLocalTransactionRequest berisi parameter berikut.
|
Nama |
Tipe |
Deskripsi |
|
TableName (wajib) |
|
Nama tabel. |
|
PrimaryKey (wajib) |
|
Nilai kunci partisi yang menentukan cakupan transaksi. Tentukan hanya kolom kunci primer pertama dari tabel. |
Operasi data dalam transaksi
PutRowChange, UpdateRowChange, DeleteRowChange, SingleRowQueryCriteria, dan RangeRowQueryCriteria berisi parameter umum berikut saat digunakan dalam transaksi.
|
Nama |
Tipe |
Deskripsi |
|
TransactionId (wajib) |
|
ID transaksi lokal yang dikembalikan oleh |
Commit atau batalkan transaksi lokal
CommitTransactionRequest dan AbortTransactionRequest berisi parameter berikut.
|
Nama |
Type |
Deskripsi |
|
TransactionId (wajib) |
|
ID transaksi lokal yang akan di-commit atau dibatalkan. |
Tanggapan
StartLocalTransactionResponse berisi informasi bisnis berikut.
|
Field |
Tipe |
Deskripsi |
|
|
|
ID transaksi lokal baru, yang digunakan dalam operasi data serta untuk commit atau abort transaksi. |
Batasan
-
Kolom kunci primer dengan auto-increment dan transaksi lokal tidak dapat digunakan secara bersamaan.
-
Transaksi lokal menggunakan kunci pesimistis untuk kontrol konkurensi. Selama transaksi berlangsung, operasi tulis untuk nilai kunci partisi tersebut dikunci. Hanya permintaan tulis yang menyertakan ID transaksi yang dapat berhasil. Server melepas kunci tulis tersebut ketika transaksi di-commit, dibatalkan, atau timeout.
-
Transaksi dapat aktif hingga 60 detik. Jika interval antara dua operasi melebihi 60 detik, server secara otomatis membatalkan transaksi tersebut.
-
Jika permintaan pembuatan transaksi lokal mengalami timeout, transaksi tersebut mungkin telah berhasil dibuat di server. Tunggu hingga transaksi tersebut timeout sebelum membuat transaksi lain.
-
Transaksi lokal yang belum di-commit dapat menjadi tidak valid. Jika hal ini terjadi, ulangi operasi dalam transaksi tersebut.
-
Hanya satu permintaan yang dapat menggunakan ID transaksi pada satu waktu. Permintaan konkuren yang menggunakan ID transaksi yang sama akan gagal.
-
Permintaan tulis dalam transaksi harus menggunakan nilai kunci partisi yang digunakan saat membuat transaksi. Permintaan baca tidak tunduk pada pembatasan ini.
-
Saat Anda menggunakan
BatchWriteRowuntuk menulis baris dalam transaksi, semua baris dalam permintaan tersebut harus berasal dari tabel tempat transaksi dibuat. -
Transaksi dapat menulis hingga 4 MB data. Jumlah data tersebut diakumulasi berdasarkan aturan perhitungan untuk permintaan tulis biasa.
-
Jika tidak ada versi yang ditentukan untuk kolom atribut, server akan menghasilkan versi berdasarkan aturan untuk operasi tulis biasa saat data ditulis, bukan saat transaksi di-commit.
-
Kegagalan operasi baca atau tulis tidak membatalkan transaksi. Anda dapat mencoba ulang permintaan tersebut atau membatalkan transaksi.
Contoh
Baca baris dalam transaksi lokal
Contoh berikut membaca satu baris dalam transaksi lokal yang sudah ada. Untuk transaksi read-only, commit dan abort memiliki efek yang sama: keduanya melepas transaksi.
criteria := &tablestore.SingleRowQueryCriteria{
TableName: "example_table",
PrimaryKey: rowKey,
MaxVersion: 1,
TransactionId: transactionID,
}
response, err := client.GetRow(
&tablestore.GetRowRequest{SingleRowQueryCriteria: criteria},
)
if err != nil {
log.Fatal(err)
}
fmt.Println(response.Columns)
_, err = client.CommitTransaction(
&tablestore.CommitTransactionRequest{TransactionId: transactionID},
)
if err != nil {
log.Fatal(err)
}