您使用的乐观锁具有
@DynamoDBVersionAttribute
,而服务器上的版本值与客户端的值不同。
您在使用
DynamoDBMapper
与
DynamoDBSaveExpression
保存数据时指定了自己的条件约束,而这些约束失败了。
DynamoDB 全局表在并发更新之间使用“以最后写入者为准”原则。如果使用全局表,则以最后写入者策略为准。因此,在这种情况下,锁定策略无法按预期方式工作。
DynamoDBMapper
事务写入操作在同一对象中不支持
@DynamoDBVersionAttribute
注释和条件表达式。如果事务写入中的对象使用
@DynamoDBVersionAttribute
进行了注释,并且还包含条件表达式,则将引发 SdkClientException。
例如,以下 Java 代码定义的
CatalogItem
类具有多个属性。
Version
属性由
@DynamoDBVersionAttribute
注释进行标记。
例
@DynamoDBTable(tableName="ProductCatalog")
public class CatalogItem {
private Integer id;
private String title;
private String ISBN;
private Set<String> bookAuthors;
private String someProp;
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 Set<String> getBookAuthors() { return bookAuthors; }
public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; }
@DynamoDBIgnore
public String getSomeProp() { return someProp;}
public void setSomeProp(String someProp) {this.someProp = someProp;}
@DynamoDBVersionAttribute
public Long getVersion() { return version; }
public void setVersion(Long version) { this.version = version;}
}
您可以将
@DynamoDBVersionAttribute
注释应用到基元封装类提供的可为空的类型 (例如
Long
和
Integer
)。
乐观锁对这些
DynamoDBMapper
方法具有以下影响:
save
— 对于新项目,
DynamoDBMapper
分配初始版本号 1。如果您检索项目,然后更新它的一个或多个属性,并尝试保存所做更改,那么只有在客户端和服务器端的版本号匹配时保存操作才能成功。
DynamoDBMapper
会自动递增版本号。
delete
—
delete
方法接受对象作为参数,并且
DynamoDBMapper
会在删除项目之前执行版本检查。在请求中指定
DynamoDBMapperConfig.SaveBehavior.CLOBBER
可以禁用版本检查。
DynamoDBMapper
中的内部乐观锁实现利用了 DynamoDB 提供的有条件更新和有条件删除支持。
transactionWrite
—
Put
— 对于新项目,
DynamoDBMapper
分配初始版本号 1。如果您检索项目,然后更新它的一个或多个属性,并尝试保存所做更改,那么只有在客户端和服务器端的版本号匹配时放置操作才能成功。
DynamoDBMapper
会自动递增版本号。
Update
— 对于新项目,
DynamoDBMapper
分配初始版本号 1。如果您检索项目,然后更新它的一个或多个属性,并尝试保存所做更改,那么只有在客户端和服务器端的版本号匹配时更新操作才能成功。
DynamoDBMapper
会自动递增版本号。
Delete
—
DynamoDBMapper
会在删除项目之前执行版本检查。仅当客户端与服务器端的版本号相匹配时,删除操作才会成功。
ConditionCheck
—
ConditionCheck
操作不支持
@DynamoDBVersionAttribute
注释。当
ConditionCheck
项目使用
@DynamoDBVersionAttribute
进行了注释时,将引发 SdkClientException。
禁用乐观锁
要禁用乐观锁,您可以将
DynamoDBMapperConfig.SaveBehavior
枚举值从
UPDATE
更改为
CLOBBER
。您可以通过创建可跳过版本检查的
DynamoDBMapperConfig
实例,然后在所有请求中使用此实例来实现这一目的。有关
DynamoDBMapperConfig.SaveBehavior
和其他可选
DynamoDBMapper
参数的信息,请参阅
DynamoDBMapper 的可选配置设置
。
您也可以针对特定操作设置锁定行为。例如,以下 Java 代码段使用
DynamoDBMapper
保存目录项目。它可以通过将可选
DynamoDBMapperConfig.SaveBehavior
参数添加到
DynamoDBMapperConfig
方法来指定
save
。
transactionWrite 方法不支持 DynamoDBMapperConfig.SaveBehavior 配置。不支持对 transactionWrite 禁用乐观锁。
例
DynamoDBMapper mapper = new DynamoDBMapper(client);
// Load a catalog item.
CatalogItem item = mapper.load(CatalogItem.class, 101);
item.setTitle("This is a new title for the item");