首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DynamoDB -如何使用ServiceStack.Aws实现乐观锁定

DynamoDB -如何使用ServiceStack.Aws实现乐观锁定
EN

Stack Overflow用户
提问于 2021-08-19 11:53:08
回答 1查看 273关注 0票数 2

目前,我正在使用ServiceStack.Aws v5.9.0与DynamoDB通信。我使用了PutItem来创建和更新一个条目,而不会在并发处理时预测数据丢失。

代码语言:javascript
复制
public class Customer
{
   [HashKey]
   public int CustomerId { get; set; }
   [AutoIncrement]
   public int SubId { get; set; }
   public string CustomerType { get; set; }
   public string LastName { get; set; }
   public string FirstName { get; set; }
   ...//and hundreds of fields here
}

public class CustomerDynamo
{
   private readonly IPocoDynamo db;
   //Constructor
   public CustomerDynamo() 
   {
      var dynamoClient = new AmazonDynamoDBClient(_region);
      var entityType = typeof(Customer);
      var tableName = entityType.Name;
      entityType.AddAttributes(new AliasAttribute(name: tableName));
      db = new PocoDynamo(dynamoClient) { ConsistentRead = true }.RegisterTable(tableType: entityType);
   }

   public Customer Update(Customer customer)
   {
      customer.ModifiedDate = DateTime.UtcNow;
      db.PutItem(customer);
      return customer;
   }
}

在每个需要更新客户数据的服务/异步任务中都调用上述Update方法。参考这篇AWS文章,我决定实现乐观锁定,以避免并发请求的问题。https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBContext.VersionSupport.html

假设VersionNumber将是乐观锁定的关键。因此,我将VersionNumber添加到客户模型中。

代码语言:javascript
复制
public class Customer
{
   [HashKey]
   public int CustomerId { get; set; }
   [AutoIncrement]
   public int SubId { get; set; }
   public string CustomerType { get; set; }
   public string LastName { get; set; }
   public string FirstName { get; set; }
   ...//and hundreds of fields here
   [DynamoDBVersion]
   public int? VersionNumber { get; set; }
}
  1. 结果是VersionNumber没有更新,而应该自动递增。我认为这仅仅是因为PutItem将覆盖整个现有项目。这是正确的吗?
  2. 我认为我需要在更新方法中从PutItem更改为UpdateItem。问题是如何动态生成与UpdateItem一起使用的表达式?

提前感谢您的帮助!

更新:

感谢@神话提供了关于DynamoDBVersion属性的有用信息。然后,我尝试删除DynamoDBVersion并使用UpdateExpression of PocoDynamo,如下所示

代码语言:javascript
复制
public Customer Update(Customer customer)
{
   customer.ModifiedDate = DateTime.UtcNow;
   var expression = db.UpdateExpression<Customer>(customer.CustomerId).Set(() => customer);
   expression.ExpressionAttributeNames = new Dictionary<string, string>() 
   { 
      { "#Version", "VersionNumber" } 
   };
   expression.ExpressionAttributeValues = new Dictionary<string, AttributeValue>() 
   {
      { ":incr", new AttributeValue { N = "1" } },
      { ":zero", new AttributeValue { N = "0" } }
   };
   expression.UpdateExpression = "SET #Version = if_not_exists(#Version, :zero) + :incr";
   if (customer.VersionNumber.HasValue)
   {
      expression.Condition(c => c.VersionNumber == customer.VersionNumber);
   }
   var success = db.UpdateItem(expression);
}

但是,除了VersionNumber之外,更改不会保存。

EN

回答 1

Stack Overflow用户

发布于 2021-08-19 12:33:39

[DynamoDBVersion]是一个AWS对象持久性模型属性,用于与AWS的DynamoDBContext一起使用,而不是用于PocoDynamo。也就是说,[DynamoDB*]属性是PocoDynamo使用的唯一属性:[DynamoDBHashKey][DynamoDBRangeKey],所有其他[DynamoDB*]属性都用于AWS的对象持久性模型库。

需要时,您可以使用以下方式访问AWS的IAmazonDynamoDB

代码语言:javascript
复制
var db = new PocoDynamo(awsDb);
var awsDb = db.DynamoDb;

以下是可能相关的PocoDynamo的UpdateItem API文档

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68847367

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档