amazonweb服务-使用DynamoDB将INSERT或UPDATE作为单个操作执行



我们使用DynamoDB来计算用户操作,必须插入或更新项目,这取决于它已经存在的内容。代码还必须更新计数器。现在我们有两个步骤:

using (var client = AWSClientFactory.CreateAmazonDynamoDBClient(RegionEndpoint.USEast1))
{
    var table = Table.LoadTable(client, TableName);
    var item = await table.GetItemAsync(id);
    if (item == null)
    {
        // row not exists -> insert & return 1
        var document = new Document();
        document["Id"] = id;
        document["Counter"] = 1;
        await table.PutItemAsync(document);
        return 1;
    }
    // row exists -> increment counter & update
    var counter = item["Counter"].AsInt();
    item["Counter"] = counter + 1;
    await table.UpdateItemAsync(item);
    return counter + 1;
}

代码的问题在于它增加了延迟时间&服务器负载。我更愿意做一次手术。我认为条件表达式应该可以做到这一点,但我不知道如何使用.NET SDK来实现这一点。

要小心自己递增计数器,因为如果应用程序的多个实例可以递增计数器,则可能会出现竞争条件。而是使用DynamoDB原子计数器。例如,我的ruby代码使用以下(较旧的(递增计数器的方法调用UpdateItem API:

{"counter" => {value: {n: "1"}, action: "ADD"}}

更新的方法是使用更新表达式,我还没有实现它。此外,如果计数器/项还不存在,它将假定值为0,并将计数器递增到1。

您的代码中有一个竞赛条件。两个不同的工作人员可能同时创建项目。

推荐的模式是:

  • 为项创建"如果不存在"操作
  • 原子计数器更新"计数">

因此,在这种情况下,您将只有2个操作(和正确的行为(,而不是3个操作(获取、放置、更新(-也有竞争条件

希望这能有所帮助。

相关内容

  • 没有找到相关文章

最新更新