Dynamodb Condition update

可以使用 PutItem, UpdateItem, DeleteItem 操作DynamoDB.

在进行这些操作时,可以使用condition expression来决定更改的规则

Put

在put操作时,如果key已经存在,原来记录会被覆盖掉,可以使用条件表达式:

aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json \
    --condition-expression "attribute_not_exists(Id)"

这样只有key 不存在时才会更新成功。

Conditional Deletes

To perform a conditional delete, you use a DeleteItem operation with a condition expression. The condition expression must evaluate to true in order for the operation to succeed; otherwise, the operation fails.

Consider the item from Condition Expressions .

{
    "Id": {
        "N": "456"
    },
    "Price": {
        "N": "650"
    },
    "ProductCategory": {
        "S": "Sporting Goods"
    }
}

Suppose that you wanted to delete the item, but only under the following conditions:

  • The ProductCategory is either “Sporting Goods” or “Gardening Supplies.”
  • The Price is between 500 and 600.

The following example tries to delete the item.

aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"456"}}' \
    --condition-expression "(ProductCategory IN (:cat1, :cat2)) and (Price between :lo and :hi)" \
    --expression-attribute-values file://values.json

The arguments for --expression-attribute-values are stored in the values.json file.

{
    ":cat1": {"S": "Sporting Goods"},
    ":cat2": {"S": "Gardening Supplies"},
    ":lo": {"N": "500"},
    ":hi": {"N": "600"}
}

并发

  • Dynamodb有个特性叫“Conditional Update/Delete”
  • Dynamodb使用乐观锁。

image-20191005142136365

Conditional Writes

By default, the DynamoDB write operations (PutItem, UpdateItem, DeleteItem) are unconditional: Each operation overwrites an existing item that has the specified primary key.

DynamoDB optionally supports conditional writes for these operations. A conditional write succeeds only if the item attributes meet one or more expected conditions. Otherwise, it returns an error. Conditional writes are helpful in many situations. For example, you might want a PutItem operation to succeed only if there is not already an item with the same primary key. Or you could prevent an UpdateItem operation from modifying an item if one of its attributes has a certain value.

Conditional writes are helpful in cases where multiple users attempt to modify the same item. Consider the following diagram, in which two users (Alice and Bob) are working with the same item from a DynamoDB table.

img

Suppose that Alice uses the AWS CLI to update the Price attribute to 8.

aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --expression-attribute-values file://expression-attribute-values.json

The arguments for --expression-attribute-values are stored in the file expression-attribute-values.json:

{
    ":newval":{"N":"8"}
}
 

Now suppose that Bob issues a similar UpdateItem request later, but changes the Price to 12. For Bob, the --expression-attribute-values parameter looks like the following.

{
    ":newval":{"N":"12"}
}
 

Bob’s request succeeds, but Alice’s earlier update is lost.

To request a conditional PutItem, DeleteItem, or UpdateItem, you specify a condition expression. A condition expression is a string containing attribute names, conditional operators, and built-in functions. The entire expression must evaluate to true. Otherwise, the operation fails.

Now consider the following diagram, showing how conditional writes would prevent Alice’s update from being overwritten.

img

Alice first tries to update Price to 8, but only if the current Price is 10.

aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --condition-expression "Price = :currval" \
    --expression-attribute-values file://expression-attribute-values.json
 

The arguments for --expression-attribute-values are stored in the expression-attribute-values.json file.

{
    ":newval":{"N":"8"},
    ":currval":{"N":"10"} 
}
        

Alice’s update succeeds because the condition evaluates to true.

Next, Bob attempts to update the Price to 12, but only if the current Price is 10. For Bob, the --expression-attribute-values parameter looks like the following.

{
    ":newval":{"N":"12"},
    ":currval":{"N":"10"} 
}
        

Because Alice has previously changed the Price to 8, the condition expression evaluates to false, and Bob’s update fails.