我在dynamodb中有一个表,我需要一次更新多个相关项目(由于400kb大小限制,我无法将所有数据放在一个项目中)。 如何确保多行成功更新或不更新。
最终目标是在更新后读取一致的数据。
答案 0 :(得分:6)
在November 27th, 2018, transactions for Dynamo DB were announced.上链接的文章中:
DynamoDB事务为开发人员在单个AWS帐户和区域内的一个或多个表上提供原子性,一致性,隔离性和持久性(ACID)。在构建需要协调地插入,删除或更新多个项目作为单个逻辑业务操作的一部分的应用程序时,可以使用事务。 DynamoDB是唯一支持跨多个分区和表进行事务处理的非关系数据库。
新的API是:
TransactWriteItems ,这是一个批处理操作,其中包含一个写集以及一个或多个PutItem,UpdateItem和DeleteItem操作。 TransactWriteItems可以选择检查进行更新之前必须满足的先决条件。这些条件可能涉及与写入集中相同或不同的项目。如果不满足任何条件,交易将被拒绝。
TransactGetItems ,这是一个批处理操作,其中包含一个读取集以及一个或多个GetItem操作。如果对作为活动写入事务一部分的项目发出了TransactGetItems请求,则会取消读取事务。要获取先前提交的值,可以使用标准读取。
链接的文章中还有一个JavaScript示例:
data = await dynamoDb.transactWriteItems({
TransactItems: [
{
Update: {
TableName: 'items',
Key: { id: { S: itemId } },
ConditionExpression: 'available = :true',
UpdateExpression: 'set available = :false, ' +
'ownedBy = :player',
ExpressionAttributeValues: {
':true': { BOOL: true },
':false': { BOOL: false },
':player': { S: playerId }
}
}
},
{
Update: {
TableName: 'players',
Key: { id: { S: playerId } },
ConditionExpression: 'coins >= :price',
UpdateExpression: 'set coins = coins - :price, ' +
'inventory = list_append(inventory, :items)',
ExpressionAttributeValues: {
':items': { L: [{ S: itemId }] },
':price': { N: itemPrice.toString() }
}
}
}
]
}).promise();
答案 1 :(得分:1)
您可以像Java一样使用这个API,http://aws.amazon.com/blogs/aws/dynamodb-transaction-library/。事务库API将帮助您管理原子事务。
如果您正在使用node.js,那么使用原子计数器或条件写入还有其他解决方案。请在此处查看答案How to support transactions in dynamoDB with javascript aws-sdk?。