使用适用于Java 2的AWS开发工具包的AWS DynamoDB版本字段

将任何实体上的版本属性保存到
AWS DynamoDB数据库,它仅是表示实体已修改次数的数字表示。 首次创建实体时,可以将其设置为1,然后在每次更新时递增。

好处是立竿见影的-指示实体已被修改的次数,可用于审核实体。 此外,还有一种额外的用途是乐观锁定 ,其中仅当更新实体的持有者具有正确版本的实体时才允许更新实体。

这篇文章将详细介绍如何通过AWS开发工具包2的DynamoDB相关库引入此类字段

模型

考虑一个名为“旅馆”的模型,该模型将持久化到发电机数据库中。 在Kotlin中,可以使用以下数据类表示它:

 data class Hotel( 
     val id: String = UUID.randomUUID().toString(), 
     val name: String, 
     val address: String? = val address: String? = null , 
     val state: String? = val state: String? = null , 
     val zip: String? = val zip: String? = null , 
     val version: Long = 1L  ) 

此模型中引入了一个version字段,其初始值为1。其目的是按原样保存此字段,然后让dynamo在保存该实体时自动管理该字段的增量。

随着此模型中字段的更改,我希望按照以下内容更新版本:

DynamoDB的本地版本

使DynamoDB在本地计算机上运行非常有用,这样就不必在AWS中创建真正的DynamoDB表。

有多种方法可以做到这一点。 一种是使用的docker版本
DynamoDB Local ,可以通过以下方式启动以侦听端口4569:

 amazon/dynamodb-local: docker run -p 4569 : 8000 amazon/dynamodb-local: 1.13 

我个人的喜好是使用localstack ,站点上的说明有不同的启动方式。 我通常使用docker-compose来启动它。 在DynamoDB Local上使用localstack的原因之一是localstack提供了一套全面的AWS服务用于本地测试,而不仅仅是DynamoDB。

快速演示

我在这里的 github仓库中有完整的代码–
https://github.com/bijukunjummen/boot-with-dynamodb

使用dynamoDB的本地版本启动应用程序后,可以使用以下httpie请求创建实体:

 http : 9080 /hotels id= 4 name=name address=address zip=zip state=OR 

响应,其中version字段设置为1:

 { 
     "address" : "address" , 
     "id" : "4" , 
     "name" : "name" , 
     "state" : "OR" , 
     "version" : 1 , 
     "zip" : "zip"  } 

然后,如果实体的名称已更新:

 http PUT : 9080 /hotels/ 4 name=name1 address=address zip=zip state=OR version= 1 

版本字段将更新为2,依此类推:

 { 
     "address" : "address" , 
     "id" : "4" , 
     "name" : "name1" , 
     "state" : "OR" , 
     "version" : 2 , 
     "zip" : "zip"  } 

还要注意,如果在更新期间提供了错误的版本号,则调用将失败,因为使用此版本字段存在乐观锁定。

实施版本字段

实现版本字段取决于DynamoDB提供的功能强大的UpdateItem API。 UpdateItem API的功能之一是它包含一个“ UpdateExpression”,它是一个dsl,它显示了应如何更新不同的Dynamo属性。

对AWS DynamoDB的原始请求如下所示:

 { 
   "TableName" : "hotels" , 
   "Key" : { 
     "id" : { 
       "S" : "1" 
     } 
   }, 
   "UpdateExpression" : "\nSET #name=:name,\n #state=:state,\naddress=:address,\nzip=:zip\nADD version :inc\n " , 
   "ExpressionAttributeNames" : { 
     "#state" : "state" , 
     "#name" : "name" 
   }, 
   "ExpressionAttributeValues" : { 
     ":name" : { 
       "S" : "testhotel" 
     }, 
     ":address" : { 
       "S" : "testaddress" 
     }, 
     ":state" : { 
       "S" : "OR" 
     }, 
     ":zip" : { 
       "S" : "zip" 
     }, 
     ":inc" : { 
       "N" : "1" 
     } 
   }  } 

从文章角度看,特别关注“ ADD版本:inc”,该表达式告诉AWS DynamoDB将版本的值增加“:inc”值,该值使用“ ExpressionAttributeValues”和“ 1”单独提供。 以json格式处理原始API令人生畏,这就是AWS提供的软件开发套件(SDK)的来源,适用于Java 2的AWS开发工具包是对AWS开发工具包的重写,其重点是使用最新的Java功能和非通过线路阻塞IO。 使用适用于Java 2的AWS开发工具包,“ UpdateItem”如下所示(使用Kotlin代码):

 val updateItemRequest = UpdateItemRequest.builder() 
     .tableName(TABLE_NAME) 
     .key( 
         mapOf( 
             ID to AttributeValue.builder().s(hotel.id).build() 
         ) 
     ) 
     .updateExpression( 
     "" " 
         SET #name=:name, 
         #state=:state, 
         address=:address, 
         zip=:zip 
         ADD version :inc 
     "" " 
     ) 
     .conditionExpression( "version = :version" ) 
     .expressionAttributeValues( 
         mapOf( 
             ":${NAME}" to AttributeValue.builder().s(hotel.name).build(), 
             ":${ZIP}" to AttributeValue.builder().s(hotel.zip).build(), 
             ":${STATE}" to AttributeValue.builder().s(hotel.state).build(), 
             ":${ADDRESS}" to AttributeValue.builder().s(hotel.address).build(), 
             ":${VERSION}" to AttributeValue.builder().n(hotel.version.toString()).build(), 
             ":inc" to AttributeValue.builder().n( "1" ).build() 
         ) 
     ) 
     .expressionAttributeNames( 
         mapOf( 
             "#name" to "name" , 
             "#state" to "state" 
         ) 
     ) 
     .build()  val updateItem: CompletableFuture<UpdateItemResponse> = dynamoClient.updateItem(updateItemRequest)  return Mono.fromCompletionStage(updateItem) 
     .flatMap { 
         getHotel(hotel.id) 
     } 

高亮显示的行具有“ Update Expression”,其中所有现有字段均设置为新值,并且version属性增加了1。关于此调用的另一件事要注意的是“ conditionExpression”,这实际上是告诉DynamoDB更新的一种方式。如果条件匹配,则为属性;在此特定情况下,如果版本的现有值匹配,则为属性。 这提供了一种支持乐观锁定记录的巧妙方法。

结论

这里有很多细节–感受它的最简单方法是尝试在我的github存储库中找到的代码– https://github.com/bijukunjummen/boot-with-dynamodb 。 自述文件提供了有关如何在本地环境中运行它的详细信息。

AWS DynamoDB提供了一种巧妙的方法来管理实体上的版本字段,确保对它们进行原子更新,并为它们提供了一种用于乐观锁定的方法

翻译自: https://www.javacodegeeks.com/2020/05/aws-dynamodb-version-field-using-aws-sdk-for-java-2.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值