单条记录的 DynamoDB ACID 事务
DynamoDB ACID transaction for single record
我有一个 DynamoDB“My_Table”,索引在“lock_status”上:
{
my_pk: string,
lock_status: string,
useful_data: string,
}
是否可以让两个不同的线程在同一条记录上执行下面的更新代码?
本质上,我只希望一个线程能够访问任何给定记录的“useful_data”。为此,我在线程处理此项时通过 lockStatus“锁定”记录。我担心的是两个线程同时执行这段代码。他们都根据“ConditionExpression”找到相同的记录并锁定相同的记录。
const client = new AWS.DynamoDB.DocumentClient();
return await client.update({
TableName: 'My_Table',
Limit: 1,
UpdateExpression: 'set lockStatus = :status_locked',
ConditionExpression: 'lockStatus <> :status_available',
ExpressionAttributeValues: {
':status_locked': 'LOCKED',
':status_available': 'AVAILABLE',
},
ReturnValues: 'ALL_NEW',
}).promise();
如果我使用的是 TransactWriteItem,这似乎可以避免这个问题,但是我可以在我的简单场景中使用简单更新吗?
您可以为此使用乐观锁定 - 这个想法相当简单。
您为您的项目创建一个版本属性,该属性是一个将递增的整数。
{
pk: 123
sk: 123
version: 0
randomValue: abc
}
当您阅读要更新的项目时,您会记下当前版本号。更新项目后,您还会增加版本号。因此,如果您想更新随机值,您将写入 DynamoDB 的项目将如下所示:
{
pk: 123
sk: 123
version: 1
randomValue: newValue
}
您现在向 update 或 putitem 调用添加一个条件表达式,以确保仅在该项目的当前版本仍为 0 时才成功。
这样调用就会失败,如果其他人在您处理项目时更新了该项目,您可以再次读取、更新并再次写入。
如果调用成功,您就知道没有其他人弄乱该项目。
我还写了一篇更详细的博客 post 如果你好奇的话:link
我有一个 DynamoDB“My_Table”,索引在“lock_status”上:
{
my_pk: string,
lock_status: string,
useful_data: string,
}
是否可以让两个不同的线程在同一条记录上执行下面的更新代码?
本质上,我只希望一个线程能够访问任何给定记录的“useful_data”。为此,我在线程处理此项时通过 lockStatus“锁定”记录。我担心的是两个线程同时执行这段代码。他们都根据“ConditionExpression”找到相同的记录并锁定相同的记录。
const client = new AWS.DynamoDB.DocumentClient();
return await client.update({
TableName: 'My_Table',
Limit: 1,
UpdateExpression: 'set lockStatus = :status_locked',
ConditionExpression: 'lockStatus <> :status_available',
ExpressionAttributeValues: {
':status_locked': 'LOCKED',
':status_available': 'AVAILABLE',
},
ReturnValues: 'ALL_NEW',
}).promise();
如果我使用的是 TransactWriteItem,这似乎可以避免这个问题,但是我可以在我的简单场景中使用简单更新吗?
您可以为此使用乐观锁定 - 这个想法相当简单。 您为您的项目创建一个版本属性,该属性是一个将递增的整数。
{
pk: 123
sk: 123
version: 0
randomValue: abc
}
当您阅读要更新的项目时,您会记下当前版本号。更新项目后,您还会增加版本号。因此,如果您想更新随机值,您将写入 DynamoDB 的项目将如下所示:
{
pk: 123
sk: 123
version: 1
randomValue: newValue
}
您现在向 update 或 putitem 调用添加一个条件表达式,以确保仅在该项目的当前版本仍为 0 时才成功。
这样调用就会失败,如果其他人在您处理项目时更新了该项目,您可以再次读取、更新并再次写入。 如果调用成功,您就知道没有其他人弄乱该项目。
我还写了一篇更详细的博客 post 如果你好奇的话:link