Amazon DynamoDB
Developer Guide (API Version 2012-08-10)
« PreviousNext »
View the PDF for this guide.Go to the AWS Discussion Forum for this product.Go to the Kindle Store to download this guide in Kindle format.Did this page help you?  Yes | No |  Tell us about it...

Optimistic Locking With Version Number Using the AWS SDK for Java Object Persistence Model

The optimistic locking support in the Object Persistence model ensures that the client-side item that you are updating (or deleting) is the same as the item on the server-side. The version mismatch can happen if after you retrieve an item some other transaction updates that item on the server making your copy a stale version. Without optimistic locking, if you send an update request using your stale version, updates made by another request might be lost.

The Object Persistence model provides the @DynamoDBVersionAttribute annotation type that you can use to enable optimistic locking. To enable locking, you specify one class property to store version numbers and mark it using this annotation type. When you save an object, the corresponding item on the server will have an attribute that stores the version number. The DynamoDBMapper assigns a version number when you first save the object and increments the version number each time you update the item. Your update or delete request succeeds only if the client-side object version matches the corresponding version number of the item on the server-side.

For example, the following Java code snippet defines a CatalogItem class that has several properties. It also includes a property, Version, that is tagged with the @DynamoDBVersionAttribute annotation type.

@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {
    
    private Integer id;
    private String title;
    private String ISBN;
    private List<String> bookAuthors;
    private Long version;

    @DynamoDBHashKey(attributeName="Id")  
    public Integer getId() { return id; }
    public void setId(Integer Id) { this.id = Id; }
    
    @DynamoDBAttribute(attributeName="Title")  
    public String getTitle() { return title; }    
    public void setTitle(String title) { this.title = title; }
    
    @DynamoDBAttribute(attributeName="ISBN")  
    public String getISBN() { return ISBN; }    
    public void setISBN(String ISBN) { this.ISBN = ISBN;}
    
    @DynamoDBAttribute(attributeName = "Authors")
    public List<String> getBookAuthors() { return bookAuthors; }    
    public void setBookAuthors(List<String> bookAuthors) { this.bookAuthors = bookAuthors; }
    
    @DynamoDBVersionAttribute
    public Long getVersion() { return version; }
    public void setVersion(Long version) { this.version = version;}
}

You can apply the @DynamoDBVersion annotation to nullable types provided by the primitive wrappers classes such as Long and Integer, or you can use the primitive types int and long. We recommend that you use Integer and Long whenever possible.

Optimistic locking has the following impact on the typical CRUD operations:

  • save operation - For a new item, the DynamoDBMapper assigns an initial version number 1. If you retrieve an item, update one or more of its properties and attempt to save the changes, the save operation succeeds only if the version number on the client-side and the server-side match. The DynamoDBMapper context increments the version number. You don't need to set the version number.

  • delete operation -The delete method takes an object as parameter and the DynamoDBMapper performs a version check before deleting the item. The version check can be disabled if DynamoDBMapperConfig.SaveBehavior.CLOBBER is specified in the request.

    Note that the internal implementation of optimistic locking in the Object Persistence code uses the conditional update and the conditional delete API support in Amazon DynamoDB.

Disabling Optimistic Locking

You can configure the DynamoDBMapper to disable optimistic locking by specifying a DynamoDBMapperConfig.SaveBehavior enumeration value when using the save method. You can do this by creating a DynamoDBMapperConfig instance that skips version checking and use this instance for all your requests. For information about specifying optional DynamoDBMapper parameters, see Specifying Optional Configuration Information to the DynamoDBMapper . You can also set locking behavior for a specific operation only. For example, the following Java snippet uses the DynamoDBMapper to save a catalog item. It specifies DynamoDBMapperConfig.SaveBehavior by adding the optional DynamoDBMapperConfig parameter to the save method.

DynamoDBMapper mapper = new DynamoDBMapper(client);
// Load a catalog item.

CatalogItem item = context.load(CatalogItem.class, 101);
item.setSomeProp("value");
...
// Save the item.
mapper.save(item, 
    new DynamoDBMapperConfig(
        DynamoDBMapperConfig.SaveBehavior.CLOBBER));