为什么@DynamoDBVersionAttribute 不允许用于范围键属性?

0

【以下的问题经过翻译处理】 使用DynamodbMapper注释的Java表模型:

/**

 * Defines model for the DDB items stored in Documents table

 */

@Data // @Value not used as it cannot work with @NoArgsConstructor

@NoArgsConstructor // Required by DDBMapper for initialization

@AllArgsConstructor

@Builder(toBuilder = true)

@DynamoDBTable(tableName = DocumentModel.TABLE_NAME)

public class DocumentModel {



    public static final String TABLE_NAME = "Document";



    /**

     * Document id used to fetch a document's details.

     */

    @NonNull

    @DynamoDBHashKey

    @DynamoDBTypeConverted(converter = ACIConverter.class)

    private ACI id;



    /**

     * Version for a document, DDBMapper will update the version every time an overwrite of the same object occurs.

     */

    @DynamoDBRangeKey

    @DynamoDBVersionAttribute

    private int version;

}

我正在尝试使用DynamoDBMapper创建具有上述模型的表。 我正在遵循AWS的最佳做法:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-sort-keys.html#bp-sort-keys-version-control通过使用注释@DynamoDBVersionAttribute在范围键中对对象进行版本控制。

但是,当我尝试在使用DynamoDBLocal的测试中运行构建表时,我收到以下错误:

  [junit] Testsuite: com.amazon.dithreatmodelingservicelambda.database.DocumentDaoTest

    [junit] Tests run: 0, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 4.995 sec

    [junit]

    [junit] Testcase: com.amazon.dithreatmodelingservicelambda.database.DocumentDaoTest:	Caused an ERROR

    [junit] DocumentModel[version] could not be mapped for type int

    [junit] com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: DocumentModel[version] could not be mapped for type int

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$TableBuilder.<init>(StandardModelFactories.java:123)

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$TableBuilder.<init>(StandardModelFactories.java:132)

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$TableBuilder.<init>(StandardModelFactories.java:116)

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$StandardTableFactory.getTable(StandardModelFactories.java:107)

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.getTableModel(DynamoDBMapper.java:410)

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.generateCreateTableRequest(DynamoDBMapper.java:2270)

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.AbstractDynamoDBMapper.generateCreateTableRequest(AbstractDynamoDBMapper.java:339)

    [junit] 	at com.amazon.dithreatmodelingservicelambda.tools.TestHelper.lambda$initializeDynamoDBMapper$0(TestHelper.java:31)

    [junit] 	at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:406)

    [junit] 	at com.amazon.dithreatmodelingservicelambda.tools.TestHelper.initializeDynamoDBMapper(TestHelper.java:30)

    [junit] 	at com.amazon.dithreatmodelingservicelambda.database.DocumentDaoTest.classSetup(DocumentDaoTest.java:26)

    [junit] Caused by: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: DocumentModel[version]; auto-generated key and ALWAYS not allowed

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel$Builder.build(DynamoDBMapperFieldModel.java:427)

    [junit] 	at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$TableBuilder.<init>(StandardModelFactories.java:121)

    [junit]

    [junit]

    [junit] TEST com.amazon.dithreatmodelingservicelambda.database.DocumentDaoTest FAILED

    [junit] Testsuite: com.amazon.dithreatmodelingservicelambda.database.ZonedDateTimeConverterTest

    [junit] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.018 sec

    [junit]

    [junit] Tests FAILED

日志中最关键的错误时 "auto-generated key and ALWAYS not allowed"

在论坛中搜索后:https://forums.aws.amazon.com/message.jspa?messageID=312527 我发现AWS不建议使用@DynamoDBVersionAttribute生成的自动递增键。

为什么有 2 个相互冲突的指导,如果这里没有冲突,那么如何在使用 DynamoDBMapper 时对范围键属性启用乐观锁定?

profile picture
专家
已提问 8 个月前27 查看次数
1 回答
0

【以下的回答经过翻译处理】 你可能混淆了“版本”这个多义词的两个不同概念。使用排序键进行版本控制的最佳实践指南 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-sort-keys.html#bp-sort-keys-version-control 与审计/合规版本控制设计模式更相关。在这里,你有两种用例:

1. 使用排序键搜索“v0_”来获取最新的审计条目。
2. 使用分区键/排序键并过滤“v0_”来获取历史时间记录列表。

对于这种设计模式,不允许更新/更改历史审计数据。你只能对"v0_audit"进行更新,以使审计员可以访问最新的审计条目。当进行新的审计条目时,软件必须执行以下操作:

1. 使用排序键“v<最大版本号+1>_audit”插入新的审计条目行。
2. 将步骤1中插入数据的副本更新到使用排序键“v0_audit”的行中。

使用DynamoDBMapper的DynamoDBVersionAttribute主要是为了更新数据并防止两个不同的客户端更新表中的同一行(乐观锁定)。每次更新时,每行都将更新行版本号。即每个客户端在更新数据之前将最初获得该行的当前版本。当客户端尝试更新该现有行时,客户端所拥有的版本需要与该行中存储的版本匹配,才能保存。如果版本不匹配,则客户端的更新将失败,这意味着另一个客户端已经更新了该行。

希望这样能让你明白,

  • Randy
profile picture
专家
已回答 8 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则