将 DynamoDB 和 Amazon SDK for .NET 对象持久化模型结合使用的乐观锁
对象持久化模型中的乐观锁定支持可确保应用程序的项目版本与服务器端的项目版本相同,然后再更新或删除项目。假设您检索要更新的项目。但是,在您发送更新之前,其他一些应用程序会更新相同的项目。现在,您的应用程序有该项目的过时副本。如果没有乐观锁定,您执行的任何更新都将覆盖其他应用程序所做的更新。
对象持久化模型的乐观锁定功能提供了DynamoDBVersion
标签,您可以使用它来启用乐观锁定。要使用此功能,请向类添加一个属性以存储版本号。您可以添加DynamoDBVersion
属性添加到属性。首次保存对象时,DynamoDBContext
分配一个版本号,并且在每次更新项目时递增版本号的值。
只有在客户端对象版本与服务器中对应的项目版本号相匹配时,您的更新或删除请求才会成功。如果您的应用程序有过时的副本,则必须从服务器获取最新版本,然后才能更新或删除该项目。
下面的 C# 代码示例定义了 Book
类,其中包含对象持久性属性将其映射到 ProductCatalog
表。有 DynamoDBVersion
属性的类的 VersionNumber
属性存储版本号值。
例
[DynamoDBTable("ProductCatalog")] public class Book { [DynamoDBHashKey] //Partition key public int Id { get; set; } [DynamoDBProperty] public string Title { get; set; } [DynamoDBProperty] public string ISBN { get; set; } [DynamoDBProperty("Authors")] public List<string> BookAuthors { get; set; } [DynamoDBVersion] public int? VersionNumber { get; set; } }
注意
您可以应用DynamoDBVersion
属性仅设置为可为空的数字基本类型(例如int?
)。
乐观锁对这些 DynamoDBContext
方法具有以下影响:
-
对于新项目,
DynamoDBContext
分配初始版本号 0。如果您检索现有项目,然后更新它的一个或多个属性,并尝试保存所做更改,那么只有在客户端和服务器端的版本号匹配时保存操作才能成功,DynamoDBContext
递增版本号。您无需设置版本号。 -
Delete
方法提供重载,可以将主键值或对象作为参数,如以下 C# 代码示例所示。例
DynamoDBContext context = new DynamoDBContext(client); ... // Load a book. Book book = context.Load<ProductCatalog>(111); // Do other operations. // Delete 1 - Pass in the book object. context.Delete<ProductCatalog>(book); // Delete 2 - Pass in the Id (primary key) context.Delete<ProductCatalog>(222);
如果提供对象作为参数,则仅当对象版本与相应的服务器端项目版本匹配时,才会成功删除。但是,如果提供主键值作为参数,
DynamoDBContext
不知道任何版本号,它会删除项目而不进行版本检查。请注意,对象持久化模型代码中乐观锁定的内部实现使用 DynamoDB 中的条件更新和条件删除 API 操作。
禁用乐观锁
要禁用乐观锁定,请使用SkipVersionCheck
配置属性。您可以在创建 DynamoDBContext
时设置此属性。在这种情况下,对于您使用上下文进行的任何请求,都会禁用乐观锁定。有关更多信息,请参阅 指定 DynamoDBContext 的可选参数 。
您不需要在上下文级别设置属性,而是为特定操作禁用乐观锁定,如以下 C# 代码示例所示。该示例使用上下文删除书籍项目。Delete
方法设置可选 SkipVersionCheck
属性设置为 true,禁用版本检查。
例
DynamoDBContext context = new DynamoDBContext(client); // Load a book. Book book = context.Load<ProductCatalog>(111); ... // Delete the book. context.Delete<Book>(book, new DynamoDBContextConfig { SkipVersionCheck = true });