El Tablestore SDK for Java escribe, actualiza o elimina una fila únicamente cuando la fila destino cumple la condición especificada.
Requisitos previos
Instale Tablestore SDK for Java e inicialice un cliente.
Descripción
El contenedor Condition almacena una condición de existencia de fila (rowExistenceExpectation), una condición de columna (columnCondition), o ambas. Pase la condición configurada a setCondition() en RowPutChange, RowUpdateChange o RowDeleteChange. Estos cambios de fila también pueden incluirse en una solicitud BatchWriteRow. Si no se cumple la condición, el servidor devuelve un error y la fila permanece sin cambios.
rowChange.setCondition(condition)
new SingleColumnValueCondition(columnName, operator, columnValue)
new CompositeColumnValueCondition(logicOperator)
En el siguiente ejemplo se actualiza la fila con clave principal row1 en la tabla condition_demo solo si la fila existe. De lo contrario, el servidor devuelve un 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);
client.updateRow(new UpdateRowRequest(rowUpdateChange));
Parámetros
Condición de actualización
Condition contiene los siguientes parámetros. La condición de existencia de fila y la condición de columna pueden usarse por separado o en conjunto. No se evalúa ninguna condición cuando rowExistenceExpectation es IGNORE y columnCondition no está establecida.
|
Nombre |
Tipo |
Descripción |
|
rowExistenceExpectation (opcional) |
RowExistenceExpectation |
La condición de existencia de fila. Valores válidos:
|
|
columnCondition (opcional) |
ColumnCondition |
La condición de columna. Las subclases son |
Condición de valor de columna única
Cuando Condition.columnCondition es una SingleColumnValueCondition, contiene los siguientes parámetros.
|
Nombre |
Tipo |
Descripción |
|
columnName (obligatorio) |
String |
El nombre de la columna de atributo que se va a comprobar. |
|
operator (obligatorio) |
CompareOperator |
El operador de comparación. Valores válidos:
|
|
columnValue (obligatorio) |
ColumnValue |
El valor con el que se compara. |
|
passIfMissing (opcional) |
boolean |
Indica si se debe considerar que la fila cumple la condición cuando falta la columna de atributo destino. Valor predeterminado: Establezca este valor en |
|
latestVersionsOnly (opcional) |
boolean |
Indica si se debe comprobar únicamente la versión más reciente de los datos. Valor predeterminado: Establezca este valor en |
Condición compuesta
Cuando Condition.columnCondition es una CompositeColumnValueCondition, contiene los siguientes parámetros. Agregue subcondiciones mediante addCondition(). Puede agregar hasta 32 subcondiciones.
|
Nombre |
Tipo |
Descripción |
|
type (obligatorio) |
LogicOperator |
El operador lógico. Valores válidos:
|
|
conditions (obligatorio) |
List<ColumnCondition> |
Las subcondiciones para la operación lógica. Agregue cada subcondición con |
Ejemplos
Condición de valor de columna única
Utilice SingleColumnValueCondition para comprobar el valor de una sola columna de atributo. En el siguiente ejemplo se actualiza col2 para la fila con clave principal row1 solo cuando 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));
Condición de valor de columna compuesta
Utilice CompositeColumnValueCondition para combinar varias condiciones con operadores lógicos. Es posible anidar condiciones compuestas entre sí. En el siguiente ejemplo se construye la condición (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-condition: 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")));
// Top-level 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));
Prevención de sobreescrituras concurrentes
Implemente la operación comparar-e-intercambiar (compare-and-swap) mediante una actualización condicional: primero lea el valor actual y luego páselo como condición de actualización. La actualización se realiza correctamente solo si la columna aún conserva el valor que leyó. Si otro proceso modifica la columna entre su lectura y escritura, la actualización falla. Esto evita que sobrescriba la escritura de dicho proceso.
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("row1"))
.build();
// 1. Read the current value.
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. Perform a conditional update based on the value just read (only update if col1 still equals 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));