O recurso de atualização condicional permite atualizar dados em uma tabela apenas se as condições especificadas forem atendidas. Caso contrário, a atualização falha.
Pré-requisitos
Instância OTSClient inicializada. Para mais informações, consulte Inicializar uma instância OTSClient.
Tabela de dados criada e preenchida. Para mais informações, consulte Criar uma tabela de dados.
Funcionamento
A atualização condicional permite anexar uma condição a uma operação de gravação ou exclusão. O contêiner Condition armazena uma condição de existência de linha (rowExistenceExpectation), uma condição de coluna (columnCondition), ou ambas. Passe o objeto Condition configurado para setCondition() em RowPutChange, RowUpdateChange ou RowDeleteChange. Se a condição não for atendida, o servidor retornará um erro e a linha permanecerá inalterada.
As classes incluem:
public class Condition {
private RowExistenceExpectation rowExistenceExpectation;
private ColumnCondition columnCondition;
}
public class SingleColumnValueCondition extends ColumnCondition
public class CompositeColumnValueCondition extends ColumnCondition
O exemplo a seguir atualiza a linha com chave primária row1 na tabela condition_demo apenas quando a linha existe. Caso contrário, o servidor retorna um erro.
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());
Consulte Parâmetros para obter a referência completa dos campos de Condition, rowExistenceExpectation e columnCondition.
Parâmetros
Configure o parâmetro de condição ao usar as operações PutRow, UpdateRow, DeleteRow ou BatchWriteRow para executar uma atualização condicional.
'condition' => [
'row_existence' => <RowExistenceExpectation>
'column_condition' => <ColumnCondition>
]
Quando houver apenas uma condição de existência de linha, é possível abreviar a condição. O código de exemplo a seguir mostra a forma abreviada:
'condition' => <RowExistenceExpectation>
Os exemplos de código a seguir mostram como construir SingleColumnValueCondition e CompositeColumnValueFilter:
SingleColumnValueCondition
[
'column_name' => '<string>',
'value' => <ColumnValue>,
'comparator' => <ComparatorType>,
'pass_if_missing' => true || false,
'latest_version_only' => true || false
]
CompositeColumnValueFilter
[
'logical_operator' => <LogicalOperator>
'sub_conditions' => [
<ColumnCondition>,
<ColumnCondition>,
<ColumnCondition>,
// other conditions
]
]
|
Parâmetro |
Descrição |
|
row_existence |
Condição de existência da linha. Ao modificar uma tabela de dados, o Tablestore verifica essa condição. Se ela não for atendida, a modificação falhará e um erro será reportado. As condições de existência de linha incluem IGNORE, EXPECT_EXIST e EXPECT_NOT_EXIST. No Tablestore, RowExistenceExpectationConst::CONST_IGNORE especifica IGNORE, RowExistenceExpectationConst::CONST_EXPECT_EXIST especifica EXPECT_EXIST e RowExistenceExpectationConst::CONST_EXPECT_NOT_EXIST especifica EXPECT_NOT_EXIST.
|
|
column_name |
Nome da coluna. |
|
value |
Valor de comparação da coluna. Este parâmetro segue o formato [Valor, Tipo]. É possível especificar Integer, String, Binary, Boolean ou Double como tipo. No Tablestore, ColumnTypeConst::CONST_INTEGER especifica um valor Integer, ColumnTypeConst::CONST_STRING especifica uma string codificada em UTF-8, ColumnTypeConst::CONST_BINARY especifica um valor Binary, ColumnTypeConst::CONST_BOOLEAN especifica um valor Boolean e ColumnTypeConst::CONST_DOUBLE especifica um valor Double. Para o tipo Binary, é obrigatório especificar tanto o valor quanto o tipo. Para tipos diferentes de Binary, basta especificar o valor sem indicar o tipo. |
|
comparator |
Operador relacional usado para comparar o valor da coluna. Para informações sobre os tipos de operadores relacionais, consulte ComparatorType. Os operadores relacionais incluem EQUAL(=), NOT_EQUAL(!=), GREATER_THAN(>), GREATER_EQUAL(>=), LESS_THAN(<) e LESS_EQUAL(<=). No Tablestore, ComparatorTypeConst::CONST_EQUAL especifica EQUAL(=), ComparatorTypeConst::CONST_NOT_EQUAL especifica NOT_EQUAL(!=), ComparatorTypeConst::CONST_GREATER_THAN especifica GREATER_THAN(>), ComparatorTypeConst::CONST_GREATER_EQUAL especifica GREATER_EQUAL(>=), ComparatorTypeConst::CONST_LESS_THAN especifica LESS_THAN(<) e ComparatorTypeConst::CONST_LESS_EQUAL especifica LESS_EQUAL(<=). |
|
logical_operator |
Operador lógico usado para combinar múltiplas condições. Para informações sobre os tipos de operadores lógicos, consulte LogicalOperator. Os operadores lógicos incluem NOT, AND e OR. No Tablestore, LogicalOperatorConst::CONST_NOT especifica NOT, LogicalOperatorConst::CONST_AND especifica AND e LogicalOperatorConst::CONST_OR especifica OR. A quantidade de subcondições permitidas varia conforme o operador lógico utilizado.
|
|
pass_if_missing |
Define se a verificação de condição deve ser aprovada quando uma coluna não existir na linha. Este parâmetro é do tipo Boolean. O valor padrão é true, indicando que, se a coluna estiver ausente, a verificação é aprovada e a linha atende aos critérios de atualização. Se você definir pass_if_missing como false e a coluna não existir na linha, a verificação falhará e a linha não atenderá aos critérios de atualização. |
|
latest_version_only |
Determina se apenas a versão mais recente dos dados deve ser usada na comparação quando uma coluna possuir múltiplas versões. Este parâmetro é do tipo Boolean. O valor padrão é true, o que significa que, havendo várias versões, somente a mais recente será considerada. Ao definir latest_version_only como false em uma coluna com múltiplas versões, todas elas serão comparadas. Nesse cenário, basta que uma única versão atenda à condição para que a verificação seja aprovada e a linha cumpra os requisitos de atualização. |
Exemplos
Realizar operações em dados com base em uma condição de existência de linha
O código de exemplo a seguir demonstra como executar operações em uma linha de dados com base em sua chave primária. Neste exemplo, as operações têm êxito apenas se a linha especificada existir; caso contrário, elas falham.
$request = array (
'tables' => array (
array (
'table_name' => '<My_Table>',
'rows' => array (
array (
// PUT operation
'operation_type' => OperationTypeConst::CONST_PUT,
// The specified row is expected not to exist. If the specified row does not exist, the condition is met.
'condition' => RowExistenceExpectationConst::CONST_EXPECT_NOT_EXIST,
'primary_key' => array (
array('PK1', 'PrimaryKey'),
array('PK2', 11),
),
'attribute_columns' => array (
array('attr1', 'Tablestore'),
array('attr2', 128)
)
),
array (
// UPDATE operation
'operation_type' => OperationTypeConst::CONST_UPDATE,
// The specified row is expected to exist. If the specified row exists, the condition is met.
'condition' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
'primary_key' => array (
array('PK1', 'PrimaryKey'),
array('PK2', 22),
),
'update_of_attribute_columns'=> array(
'PUT' => array (
array('attr1', 'OTS'),
array('attr2', 256)
)
)
),
array (
// DELETE operation
'operation_type' => OperationTypeConst::CONST_DELETE,
// No row existence check is performed.
'condition' => RowExistenceExpectationConst::CONST_IGNORE,
'primary_key' => array (
array('PK1', 'PrimaryKey'),
array('PK2', 33),
)
),
)
)
)
);
$response = $otsClient->batchWriteRow ($request);
// Process each table that is returned.
foreach ($response['tables'] as $tableData) {
print "Handling table {$tableData['table_name']} ...\n";
// Process the result returned by the PutRow operation in this table.
$putRows = $tableData['rows'];
foreach ($putRows as $rowData) {
if ($rowData['is_ok']) {
// Data is written.
print "Capacity Unit Consumed: {$rowData['consumed']['capacity_unit']['write']}\n";
} else {
// Display the error information.
print "Error: {$rowData['error']['code']} {$rowData['error']['message']}\n";
}
}
}
Realizar operações em dados com base em condições de existência de linha e valores de coluna
O código de exemplo a seguir ilustra como executar operações em dados combinando condições de existência de linha e condições baseadas em valores de coluna:
$request = array (
'tables' => array (
array (
'table_name' => 'MyTable',
'rows' => array (
// Construct SingleColumnValueCondition.
array (
// UPDATE operation
'operation_type' => OperationTypeConst::CONST_UPDATE,
'condition' => array (
'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
//attr2 != 256
'column_condition' => array (
'column_name' => 'attr2',
'value' => 256,
'comparator' => ComparatorTypeConst::CONST_NOT_EQUAL
)
),
'primary_key' => array (
array('PK1', 'PrimaryKey'),
array('PK2', 11)
),
// Use attribute_columns/put to specify the column that you want to update or add.
'update_of_attribute_columns'=> array(
'PUT' => array (
array('attr1', 'OTS'),
array('attr2', 128)
)
)
),
// Construct CompositeColumnValueFilter.
array (
// UPDATE operation
'operation_type' => OperationTypeConst::CONST_UPDATE,
'condition' => array (
'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
// attr1 = 'Tablestore' and attr2 >= 256
'column_condition' => array (
'logical_operator' => LogicalOperatorConst::CONST_AND,
'sub_conditions' => array (
array (
'column_name' => 'attr2',
'value' => 256,
'comparator' => ComparatorTypeConst::CONST_GREATER_EQUAL
),
array (
'column_name' => 'attr1',
'value' => 'Tablestore',
'comparator' => ComparatorTypeConst::CONST_EQUAL
)
)
)
),
'primary_key' => array (
array('PK1', 'pkValue'),
array('PK2', 22)
),
'update_of_attribute_columns'=> array(
'PUT' => array (),
// Use attribute_columns/delete to specify the column that you want to delete.
'DELETE_ALL' => array(
'attr1',
'attr2'
)
)
),
)
)
)
);
$response = $otsClient->batchWriteRow ($request);
// Process each table that is returned.
foreach ($response['tables'] as $tableData) {
print "Handling table {$tableData['table_name']} ...\n";
// Process the result returned by the PutRow operation in this table.
$putRows = $tableData['rows'];
foreach ($putRows as $rowData) {
if ($rowData['is_ok']) {
// Data is written.
print "Capacity Unit Consumed: {$rowData['consumed']['capacity_unit']['write']}\n";
} else {
// Display the error information.
print "Error: {$rowData['error']['code']} {$rowData['error']['message']}\n";
}
}
}
Construir uma condição para aplicar bloqueio otimista e incrementar o valor de uma coluna
O exemplo de código a seguir mostra como criar uma condição para implementar bloqueio otimista e aumentar o valor de uma coluna:
// Read a row of data.
$request = [
'table_name' => 'MyTable',
'primary_key' => [ // The primary key.
['PK0', 123],
['PK1', 'abc']
],
'max_versions' => 1
];
$response = $otsClient->getRow ($request);
$columnMap = getColumnValueAsMap($response['attribute_columns']);
$col0Value = $columnMap['col0'][0][1];
// Configure conditional update for the Col0 column to increase the value of the Col0 column by 1.
$request = [
'table_name' => 'MyTable',
'condition' => [
'row_existence' => RowExistenceExpectationConst::CONST_EXPECT_EXIST,
'column_condition' => [ // If the condition is met, the data is updated.
'column_name' => 'col0',
'value' => $col0Value,
'comparator' => ComparatorTypeConst::CONST_EQUAL
]
],
'primary_key' => [ // The primary key.
['PK0', 123],
['PK1', 'abc']
],
'update_of_attribute_columns'=> [
'PUT' => [
['col0', $col0Value+1]
]
]
];
$response = $otsClient->updateRow ($request);
Para mais exemplos de código, visite PutRow@GitHub, UpdateRow@GitHub, DeleteRow@GitHub e BatchWriteRow@GitHub.