使用 DynamoDB 和 AWS SDK for .NET 物件持久性模型的樂觀鎖定 - Amazon DynamoDB

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 DynamoDB 和 AWS SDK for .NET 物件持久性模型的樂觀鎖定

物件持久性模型中的樂觀鎖定支援可確保應用程式的項目版本與伺服器端的項目版本相同,然後再更新或刪除項目。假設您要擷取待更新的項目。不過,在您傳回更新之前,某些其他應用程式會更新相同的項目。現在應用程式的項目有過時的副本。如果沒有樂觀鎖定,您執行的任何更新都會覆寫其他應用程式所做的更新。

物件持久性模型的樂觀鎖定功能提供了 DynamoDBVersion 標籤,可讓您用來啟用樂觀鎖定。若要使用此功能,請在類別中新增一項屬性,以便儲存版本編號。您可以將 DynamoDBVersion 屬性加入該屬性。當您第一次儲存物件時,DynamoDBContext 會指派版本編號,並在每次更新項目時遞增值。

只有在用戶端物件版本與伺服器端項目的對應版本編號相符時,您的更新或刪除請求才會成功。如果應用程式有過時的副本,它必須先從伺服器取得最新版本,才能更新或刪除該項目。

下列 C# 程式碼範例會定義 Book 類別,該類別具有將其映射至 ProductCatalog 資料表的物件持久性屬性。類別中的 VersionNumber 屬性裝飾了會儲存版本編號數值的 DynamoDBVersion 屬性。

範例
[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 屬性套用至可為 null 的數字基本類型 (如 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 時設定此屬性。在這種情況下,您使用內容發起的任何請求都會停用樂觀鎖定。如需詳細資訊,請參閱指定 D 的選用參數ynamoDBContext

您可以停用特定操作的樂觀鎖定,而不是在內容層級設定屬性,如下列 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 });