Tambahkan suatu kondisi ke operasi write atau delete dalam Tablestore SDK untuk Java. Tablestore hanya menjalankan operasi tersebut jika baris target memenuhi kondisi; jika tidak, sistem akan mengembalikan error. Gunakan pembaruan bersyarat untuk menerapkan kunci optimis (optimistic locking) atau untuk menghindari menimpa perubahan konkuren yang belum Anda baca.
Prasyarat
Instal Tablestore SDK untuk Java dan inisialisasi client.
Cara kerja
Pembaruan bersyarat memungkinkan Anda menambahkan suatu kondisi ke operasi write atau delete. Kontainer Condition berisi kondisi keberadaan baris (rowExistenceExpectation), kondisi kolom (columnCondition), atau keduanya. Teruskan objek Condition yang telah dikonfigurasi ke metode setCondition() pada RowPutChange, RowUpdateChange, atau RowDeleteChange. Jika kondisi tidak terpenuhi, server akan mengembalikan error dan baris tetap tidak berubah.
Kelas-kelas tersebut meliputi:
public class Condition {
private RowExistenceExpectation rowExistenceExpectation;
private ColumnCondition columnCondition;
}
public class SingleColumnValueCondition extends ColumnCondition
public class CompositeColumnValueCondition extends ColumnCondition
Contoh berikut memperbarui baris dengan kunci primary row1 pada tabel condition_demo hanya jika baris tersebut ada. Jika tidak, server akan mengembalikan error.
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
RowUpdateChange rowUpdateChange = new RowUpdateChange("condition_demo", primaryKey);
rowUpdateChange.put("col1", ColumnValue.fromString("changed_val1"));
Condition condition = new Condition();
condition.setRowExistenceExpectation(RowExistenceExpectation.EXPECT_EXIST);
rowUpdateChange.setCondition(condition);
UpdateRowResponse response = client.updateRow(new UpdateRowRequest(rowUpdateChange));
System.out.println("RequestId: " + response.getRequestId());
System.out.println("Write CU: " + response.getConsumedCapacity().getCapacityUnit().getWriteCapacityUnit());
Lihat bagian Parameters untuk referensi lengkap bidang-bidang pada Condition, rowExistenceExpectation, dan columnCondition.
Parameters
Condition
Condition adalah kontainer kondisi. Objek ini mencakup bidang kondisi keberadaan baris dan bidang kondisi kolom. Setidaknya satu bidang harus diatur.
|
Nama |
Tipe |
Deskripsi |
|
rowExistenceExpectation (opsional) |
RowExistenceExpectation |
Kondisi keberadaan baris. Nilai yang valid:
|
|
columnCondition (opsional) |
ColumnCondition |
Kondisi kolom. Subkelasnya adalah |
SingleColumnValueCondition
Buat instance dengan new SingleColumnValueCondition(columnName, operator, columnValue).
|
Nama |
Tipe |
Deskripsi |
|
columnName (wajib) |
String |
Nama kolom atribut yang akan diperiksa. |
|
operator (wajib) |
CompareOperator |
Operator perbandingan. Nilai yang valid:
|
|
columnValue (wajib) |
ColumnValue |
Nilai yang akan dibandingkan. |
|
passIfMissing (opsional) |
boolean |
Menentukan apakah baris dianggap memenuhi kondisi ketika kolom atribut target tidak ada. Default: Atur ke |
|
latestVersionsOnly (opsional) |
boolean |
Menentukan apakah hanya versi data terbaru yang diperiksa. Default: Atur ke |
CompositeColumnValueCondition
Buat instance dengan new CompositeColumnValueCondition(logicOperator). Tambahkan subkondisi menggunakan addCondition(). Anda dapat menambahkan hingga 32 subkondisi.
|
Nama |
Type |
Deskripsi |
|
type (wajib) |
LogicOperator |
Operator logika. Nilai yang valid:
|
|
conditions (wajib) |
List<ColumnCondition> |
Subkondisi untuk operasi logika. Tambahkan setiap subkondisi dengan |
Contoh
Kondisi nilai kolom tunggal
Gunakan SingleColumnValueCondition untuk memeriksa nilai satu kolom atribut. Contoh berikut memperbarui col2 untuk baris dengan kunci primary row1 hanya jika col1 == "changed_val1".
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
RowUpdateChange rowUpdateChange = new RowUpdateChange("condition_demo", primaryKey);
rowUpdateChange.put("col2", ColumnValue.fromString("new_val2"));
Condition condition = new Condition();
SingleColumnValueCondition singleCondition = new SingleColumnValueCondition(
"col1",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString("changed_val1"));
condition.setColumnCondition(singleCondition);
rowUpdateChange.setCondition(condition);
client.updateRow(new UpdateRowRequest(rowUpdateChange));
Kondisi nilai kolom komposit
Gunakan CompositeColumnValueCondition untuk menggabungkan beberapa kondisi dengan operator logika. Anda dapat menyarangkan kondisi komposit satu sama lain. Contoh berikut membangun kondisi (col1 == "changed_val1" AND col2 == "new_val2") OR (col3 == "val3").
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
RowUpdateChange rowUpdateChange = new RowUpdateChange("condition_demo", primaryKey);
rowUpdateChange.put("col1", ColumnValue.fromString("final_val1"));
// Sub-kondisi: col1 == "changed_val1" AND col2 == "new_val2"
CompositeColumnValueCondition andCondition = new CompositeColumnValueCondition(
CompositeColumnValueCondition.LogicOperator.AND);
andCondition.addCondition(new SingleColumnValueCondition(
"col1",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString("changed_val1")));
andCondition.addCondition(new SingleColumnValueCondition(
"col2",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString("new_val2")));
// Kondisi tingkat atas OR: (col1 AND col2) OR (col3)
CompositeColumnValueCondition orCondition = new CompositeColumnValueCondition(
CompositeColumnValueCondition.LogicOperator.OR);
orCondition.addCondition(andCondition);
orCondition.addCondition(new SingleColumnValueCondition(
"col3",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString("val3")));
Condition condition = new Condition();
condition.setColumnCondition(orCondition);
rowUpdateChange.setCondition(condition);
client.updateRow(new UpdateRowRequest(rowUpdateChange));
Kunci optimis dengan compare-and-swap
Terapkan compare-and-swap menggunakan pembaruan bersyarat: pertama baca nilai saat ini, lalu gunakan nilai tersebut sebagai kondisi pembaruan. Pembaruan hanya berhasil jika kolom masih memiliki nilai yang Anda baca sebelumnya. Jika proses lain memodifikasi kolom tersebut antara pembacaan dan penulisan Anda, pembaruan akan gagal. Hal ini mencegah Anda menimpa tulisan dari proses tersebut.
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
// 1. Baca nilai saat ini.
SingleRowQueryCriteria queryCriteria = new SingleRowQueryCriteria("condition_demo", primaryKey);
queryCriteria.setMaxVersions(1);
GetRowResponse getResponse = client.getRow(new GetRowRequest(queryCriteria));
String oldValue = getResponse.getRow().getLatestColumn("col1").getValue().asString();
// 2. Lakukan pembaruan bersyarat berdasarkan nilai yang baru saja dibaca (perbarui hanya jika col1 masih sama dengan oldValue).
RowUpdateChange rowUpdateChange = new RowUpdateChange("condition_demo", primaryKey);
rowUpdateChange.put("col1", ColumnValue.fromString("cas_updated"));
Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
SingleColumnValueCondition casCondition = new SingleColumnValueCondition(
"col1",
SingleColumnValueCondition.CompareOperator.EQUAL,
ColumnValue.fromString(oldValue));
casCondition.setPassIfMissing(false);
casCondition.setLatestVersionsOnly(true);
condition.setColumnCondition(casCondition);
rowUpdateChange.setCondition(condition);
client.updateRow(new UpdateRowRequest(rowUpdateChange));