问题描述
我有一个PostConfirmation
lambda触发器,它通过 GraphQL (appsync https调用)将数据添加到 DynamoDB ,然后在{{ 1}} lambda。
通过我的应用程序用户界面手动测试时,一切正常。
但是,通过Jest测试执行时,由于在DynamoDB中找不到假定的记录信息,我有50%以上的时间得到错误。
通过UI应用程序手动测试时不会发生此问题。仅当通过Jest测试执行时。
我检查了PretokenGeneration
DynamoDB记录添加PostConfirmation
的Cloudwatch时间戳,并检查了DynamoDB中的createDate。时间戳看起来还可以。
例如:
- 表示记录已添加的
PretokenGeneration
日志条目的时间戳记为PostConfirmation
。 - 添加的记录(createdAt)的 DynamoDB
2020-08-24T17:51:06.463Z
表示该记录是在createdAt
上创建的。 -
2020-08-24T17:51:06.377Z
lambda“ END RequestId:xxxxx”的时间戳记为PostConfirmation
- PretokenGeneration lambda从
2020-08-24T17:51:06.465-05:00
开始,在2020-08-24T17:51:12.866Z
处查询结果表明未找到任何记录。
有人可以帮助我或给我提示为什么会发生和/或如何解决此问题吗?预先谢谢你。
考虑到@ noel-llevares的回答,我修改了VTL模板,使其包含ConsistentRead = true,但问题仍然存在。
这里是保存操作记录的RequestMapping
2020-08-24T17:51:13.680Z
为保存操作记录的ResponseMapping
{
"logType": "RequestMapping","path": [
"createAccountMember"
],"fieldName": "createAccountMember","resolverArn": "arn:aws:appsync:xx-xxxx-x:111111111:apis/<redacted>/types/Mutation/resolvers/createAccountMember","requestId": "<redacted>","context": {
"arguments": {
"input": {
"id": "<redacted>","userID": "<redacted>","accountID": "<redacted>","membershipStatus": "active","groupsEnrolledIn": [
<redacted>
],"recordOwner": "<redacted>","createdAt": "2020-08-25T05:11:10.917Z","updatedAt": "2020-08-25T05:11:10.917Z","__typename": "AccountMember"
}
},"stash": {},"outErrors": []
},"fieldInError": false,"errors": [],"parentType": "Mutation","graphQLAPIId": "<redacted>","transformedTemplate": "\n\n\n\n\n\n\n\n{\n \"version\": \"2018-05-29\",\n \"operation\": \"PutItem\",\n \"key\": {\n \"id\": {\"S\":\"<redacted>\"}\n},\n \"attributeValues\": {\"accountID\":{\"S\":\"<redacted>\"},\"createdAt\":{\"S\":\"2020-08-25T05:11:10.917Z\"},\"recordOwner\":{\"S\":\"<redacted>\"},\"__typename\":{\"S\":\"AccountMember\"},\"id\":{\"S\":\"<redacted>\"},\"membershipStatus\":{\"S\":\"active\"},\"userID\":{\"S\":\"<redacted>\"},\"groupsEnrolledIn\":{\"L\":[{\"S\":\"<redacted>\"},{\"S\":\"<redacted>\"},{\"S\":\"<redacted>\"}]},\"updatedAt\":{\"S\":\"2020-08-25T05:11:10.917Z\"}},\n \"condition\": {\"expression\":\"attribute_not_exists(#id)\",\"expressionNames\":{\"#id\":\"id\"}}\n}\n"
}
这是为列表操作记录的请求映射。您可以看到{
"logType": "ResponseMapping","resolverArn": "<redacted>","groupsEnrolledIn": [
"<redacted>","<redacted>","<redacted>"
],"result": {
"accountID": "<redacted>","__typename": "AccountMember","id": "<redacted>","groupsEnrolledIn": [
"<redacted>","<redacted>"
],"updatedAt": "2020-08-25T05:11:10.917Z"
},"transformedTemplate": "{\"accountID\":\"<redacted>\",\"createdAt\":\"2020-08-25T05:11:10.917Z\",\"recordOwner\":\"<redacted>\",\"__typename\":\"AccountMember\",\"id\":\"<redacted>\",\"membershipStatus\":\"active\",\"userID\":\"<redacted>\",\"groupsEnrolledIn\":[\"<redacted>\",\"<redacted>\",\"<redacted>\"],\"updatedAt\":\"2020-08-25T05:11:10.917Z\"}\n"
}
consistentRead=true
这是已记录的responseMapping。您可以看到结果是一个空数组({
"logType": "RequestMapping","path": [
"listAccountMembers"
],"fieldName": "listAccountMembers","context": {
"arguments": {
"filter": {
"userID": {
"eq": "<redacted>"
}
}
},"parentType": "Query","graphQLAPIId": "<redacted>,"transformedTemplate": " \n{\"version\":\"2018-05-29\",\"limit\":100,\"consistentRead\":true,\"filter\":{\"expression\":\"(#userID = :userID_eq)\",\"expressionNames\":{\"#userID\":\"userID\"},\"expressionValues\":{\":userID_eq\":{\"S\":\"<redacted>\"}}},\"operation\":\"Scan\"}"
}
),即使该记录是先前添加的,并且我们为查询指定了items:[]
。
consistentRead=true
我还能缺少什么?
UPDATE02
我找到了可能的原因。因为我对DynamoDB的工作方式还是陌生的。查询或扫描操作按键获取结果。在这种情况下,不涉及任何键,因此它将考虑限制的情况下获取所有记录。在我的情况下为100,然后应用过滤器。因此,如果添加的记录不在前100个结果中,那么除非我进行分页,否则找不到该记录(不利于Muy的特定需求)。
TL; DR :我将查询更改为使用@key指令,并将userID作为键字段,并且问题已经消失,因为que字段是GSI且我希望检索的记录数这样的分区远小于100的限制。完成取消之前所做的调整后,我会将此添加为答案的一部分。
解决方法
DynamoDB在默认情况下最终是 。
当您从DynamoDB表中读取数据时,响应可能无法反映最近完成的写操作的结果。响应中可能包含一些过时的数据。如果您在短时间内重复读取请求,则响应应返回最新数据。
如果需要立即阅读刚写的内容,则可以选择使用高度一致的读取。通常,这是通过在DynamoDB调用中将ConsistentRead
设置为true
来完成的。
我找到了根本原因。查询或扫描操作按键获取结果。在这种情况下,不涉及任何键,因此它将所有记录都考虑到了限制,在本例中为100,然后应用了过滤器。因此,如果添加的记录不在前100个结果中,那么除非我进行分页(否则无法满足我的特定需求),否则找不到该记录。我没有注意到这一点,因为我是DynamoDB的新手。但是,感谢@ noel-llevares,我进行了更深入的研究以找到解决方案。
解决方案是将查询更改为使用名称为“ byUsername”的@key
伪指令,该伪指令以AccountMember
作为键字段存在于userID
类型中,并且问题已经解决了,因为que字段是GSI,我希望通过这种分区检索的记录数远远少于100个限制。