DynamoDB快速且可扩展的全部原因是基于最终一致的事实。但与此同时,此ConsistentRead
选项带有get
,batchGet
和query
之类的操作,可帮助您确保所读取的数据是最新的。
我的问题是关于update
操作。首先,它没有ConsistentRead
选项(一个原因可能是update
未被读取!)。但同时,您可以使用ConditionExpression
以原子方式更新记录,如下所示:
await docClient.update({
TableName: 'SomeTable',
Key: {id},
UpdateExpression: "set #status = :new_status",
ConditionExpression: '#status = :old_status',
ExpressionAttributeNames: {
"#status": "status",
},
ExpressionAttributeValues: {
":old_status": "available",
":new_status": "done",
},
}).promise()
这将确保在更新时,旧值是available
,如果不是,则操作将失败并抛出异常。因此,从某种意义上讲,您可以说update
是高度一致的。
但是我的问题是关于一种情况,您需要确保该记录存在。假设您有一个插入记录的函数。另一个更新同一记录(根据其id
)。我担心的是,如果由于最终DynamoDB的一致性而在执行update
操作时,没有记录匹配且更新失败。如前所述,update
操作没有带有ConsistentRead
选项来使其高度一致。
这是一个有效的问题吗?有什么我可以做些帮助的吗?
答案 0 :(得分:1)
没有强烈一致的更新。 强一致性适用于读取,基本上,写入后立即查看的数据对于实体的所有观察者而言都是一致的。
当您的应用程序将数据写入DynamoDB表并收到HTTP 200响应(OK)时,就会发生写入(在至少一个存储位置中),并且该写入是持久的。最终,所有存储位置的数据通常保持一秒或更短的时间一致。然后,您可以选择以最终或高度一致性的方式读取该数据。
对同一项目的并发写入应采用乐观并发处理,您可以使用DynamoDB事务库(适用于Java的AWS开发工具包)进行有条件的写入。
如果您需要原子地更新多个项目,则可以使用DynamoDB事务。
DynamoDB事务为开发人员提供了原子性,一致性, 跨一个表中的一个或多个表的隔离和持久性(ACID) 一个AWS帐户和区域。您可以在构建时使用交易 需要协调的插入,删除或更新的应用程序 多个项目作为单个逻辑业务操作的一部分。
https://aws.amazon.com/blogs/aws/new-amazon-dynamodb-transactions/
或者,您的用例可能会受益于 DynamoDB全局表,该表使用并发写入之间的“最后写入者获胜”调节。