DynamoDB ADD Transaction Fails Intermittently for no Apparent Reason - amazon-dynamodb

I am having an intermittent problem with DynamoDB with a writing a bunch of entries. I cannot see what the problem and the weird thing the problem occurs in a place where there is no ConditionExpression. This exception happens about 1 in 10 times.
docClient.transactWrite(transaction).promise() with:
{
"TransactItems": [
{
"Update": {
"TableName": "protect-dev-stepfunction-ScanAggregation",
"Key": {
"pk": "#ScanCount#",
"sort": "#Total"
},
"UpdateExpression": "ADD queued :queued, runningFiles :runningFiles",
"ExpressionAttributeValues": {
":queued": 1,
":runningFiles": 0
},
"ReturnValues": "UPDATED_NEW"
}
},
{
"Update": {
"TableName": "protect-dev-stepfunction-ScanAggregation",
"Key": {
"pk": "#ScanCount#",
"sort": "#Tenant#pwc"
},
"UpdateExpression": "SET isTenant = :isTenant ADD queued :queued, runningFiles :runningFiles",
"ExpressionAttributeValues": {
":queued": 1,
":runningFiles": 0,
":isTenant": true
},
"ReturnValues": "UPDATED_NEW"
}
},
{
"Put": {
"TableName": "protect-dev-stepfunction-Jobs",
"Item": {
"createdAt": "2020-05-11 05:25:58.770369",
"scanId": "1161",
"tenantId": "pwc",
"TaskToken": "AAAAKgAAAAIAAAAAAAAAAb67i0NKEMIMzPxx5gzBSG8BhJwwVpTcsItdwbbkeOzPqefqQdqUu7yL3MMKLX3BR6ATsol4d60iFoOhDbR6WKmtukG5VH0rUHbxf8NMGcnZ+xhvD1bTyJbh1z2KEAHjQixI8sP/fhH065sygK9s8PS9XyvU2L/mEWcrn0ZGBLk+HDhHE2cwscYK2GYeKdVVthzCwgZ220tyYBHZBt3BXfKmjs3/8Xru8E0lk345Ub/mbalcQMTGPIYskk24UtnJNJJ5Qw9KSDBWl4e0DD0XULfcwWqsLZhVPwXS/e4j2XGE9k6XexusItElQAyopZ4njcU9YEPcchfsynDn0WptXpEMmO1gDYqE+oDaASazGIC3Oms7PhpD0XB9oApO84NvSik1q9VtXrnO5FEcBi5wG4GhYk2216Ga9lhc+S0luUIHfQQrkHtFPsw4uCaXTjTpCjCNG3wZqBjbS3GDbDnsW0yey74pc1FeEdB46os6v1OtGhjQBBbIlBS7L8t7HqNOtDrnBsqDort2u7Td0LUyp9YEksacSs4DlxKHtQ9aysxJVpFJVTGnrAuxfXcafo63R6aU8O764+6Nbm/QBWUJOdvkSQ5IaSDevqeaeLzHgeqY4KiXfCaRt2WYXljOTNucp5N8yr6ZAYGDGRrIIRiF5DY=",
"priority": "3",
"fileId": "3179",
"pk": "pwc",
"sort": "3-1161_3179",
"scanStatus": "SUBMITTED",
"rjk": "3-1161_3179"
},
"ConditionExpression": "attribute_not_exists(pk) and attribute_not_exists(sort)"
}
}
]
}{
"TransactItems": [
{
"Update": {
"TableName": "protect-dev-stepfunction-ScanAggregation",
"Key": {
"pk": "#ScanCount#",
"sort": "#Total"
},
"UpdateExpression": "ADD queued :queued, runningFiles :runningFiles",
"ExpressionAttributeValues": {
":queued": 1,
":runningFiles": 0
},
"ReturnValues": "UPDATED_NEW"
}
},
{
"Update": {
"TableName": "protect-dev-stepfunction-ScanAggregation",
"Key": {
"pk": "#ScanCount#",
"sort": "#Tenant#pwc"
},
"UpdateExpression": "SET isTenant = :isTenant ADD queued :queued, runningFiles :runningFiles",
"ExpressionAttributeValues": {
":queued": 1,
":runningFiles": 0,
":isTenant": true
},
"ReturnValues": "UPDATED_NEW"
}
},
{
"Put": {
"TableName": "protect-dev-stepfunction-Jobs",
"Item": {
"createdAt": "2020-05-11 05:25:58.770369",
"scanId": "1161",
"tenantId": "pwc",
"TaskToken": "AAAAKgAAAAIAAAAAAAAAAb67i0NKEMIMzPxx5gzBSG8BhJwwVpTcsItdwbbkeOzPqefqQdqUu7yL3MMKLX3BR6ATsol4d60iFoOhDbR6WKmtukG5VH0rUHbxf8NMGcnZ+xhvD1bTyJbh1z2KEAHjQixI8sP/fhH065sygK9s8PS9XyvU2L/mEWcrn0ZGBLk+HDhHE2cwscYK2GYeKdVVthzCwgZ220tyYBHZBt3BXfKmjs3/8Xru8E0lk345Ub/mbalcQMTGPIYskk24UtnJNJJ5Qw9KSDBWl4e0DD0XULfcwWqsLZhVPwXS/e4j2XGE9k6XexusItElQAyopZ4njcU9YEPcchfsynDn0WptXpEMmO1gDYqE+oDaASazGIC3Oms7PhpD0XB9oApO84NvSik1q9VtXrnO5FEcBi5wG4GhYk2216Ga9lhc+S0luUIHfQQrkHtFPsw4uCaXTjTpCjCNG3wZqBjbS3GDbDnsW0yey74pc1FeEdB46os6v1OtGhjQBBbIlBS7L8t7HqNOtDrnBsqDort2u7Td0LUyp9YEksacSs4DlxKHtQ9aysxJVpFJVTGnrAuxfXcafo63R6aU8O764+6Nbm/QBWUJOdvkSQ5IaSDevqeaeLzHgeqY4KiXfCaRt2WYXljOTNucp5N8yr6ZAYGDGRrIIRiF5DY=",
"priority": "3",
"fileId": "3179",
"pk": "pwc",
"sort": "3-1161_3179",
"scanStatus": "SUBMITTED",
"rjk": "3-1161_3179"
},
"ConditionExpression": "attribute_not_exists(pk) and attribute_not_exists(sort)"
}
}
]
}
And I get this stacktrace:
TransactionCanceledException: Transaction cancelled, please refer cancellation reasons for specific reasons [TransactionConflict, TransactionConflict, None]
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:51:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
message:
'Transaction cancelled, please refer cancellation reasons for specific reasons [TransactionConflict, TransactionConflict, None]',
code: 'TransactionCanceledException',
time: 2020-05-11T05:26:00.972Z,
requestId: 'ABKB5RCR30SDASOL3KGS5KEBUJVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 32.29530018146246 }

The error says it's a "TransactionConflict", which the documentation says can happen in these scenarios:
A PutItem, UpdateItem, or DeleteItem request for an item conflicts with an ongoing TransactWriteItems request that includes the same item.
An item within a TransactWriteItems request is part of another ongoing TransactWriteItems request.
An item within a TransactGetItems request is part of an ongoing TransactWriteItems, BatchWriteItem, PutItem, UpdateItem, or DeleteItem request.
In your case, it looks like the 2nd scenario. How much concurrency is there on your records?

Related

ConditionalCheckFailedException: The conditional request failed (Nested field)

I have a DDB entry as below
RequestId:'1234567890' // Partition key
LastScanDateTime: '2023-01-12T11:00:00.111Z'
SubjectUpdateCounter: {
Maths: 1,
English: 1
}
I'm trying to update the entry and below is the update query.
{
"TableName": "EmpDetails",
"Key": {
"RequestId": {
"S": "1234567890"
}
},
"ConditionExpression": "(#subjectUpdateCounter > :subjectUpdateCounterLimit)",
"UpdateExpression": "ADD #subjectUpdateCounter :dec SET LastScanDateTime = :LastScanDateTime,",
"ExpressionAttributeValues": {
":dec": {
"N": "-1"
},
":LastScanDateTime": {
"S": "2023-02-13T18:14:52.143Z"
},
":subjectUpdateCounterLimit": {
"N": "0"
}
},
"ReturnValues": "NONE",
"ExpressionAttributeNames": {
"#subjectUpdateCounter": "SubjectUpdateCounter.Maths"
}
}
Getting below error
ConditionalCheckFailedException: The conditional request failed
....
....
'$fault': 'client',
'$metadata': {
httpStatusCode: 400,
requestId: '12345ygfsdfagagdf',
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
__type: 'com.amazonaws.dynamodb.v20120810#ConditionalCheckFailedException'
}
My current value in SubjectUpdateCounter.Maths is greater than 0, so the condition should succeed and this query should decrement the value of SubjectUpdateCounter.Maths to 0.
Why is the query throwing the above exception?
Your issue is here:
"ExpressionAttributeNames": {
"#subjectUpdateCounter": "SubjectUpdateCounter.Maths"
}
This means DynamoDB is looking for an attribute named "SubjectUpdateCounter.Maths" but there is none, as its a nested value you are looking for.
Your request should look like the following:
{
"TableName": "EmpDetails",
"Key": {
"RequestId": {
"S": "1234567890"
}
},
"ConditionExpression": "(#subjectUpdateCounter.#maths > :subjectUpdateCounterLimit)",
"UpdateExpression": "ADD #subjectUpdateCounter.#maths :dec SET LastScanDateTime = :LastScanDateTime,",
"ExpressionAttributeValues": {
":dec": {
"N": "-1"
},
":LastScanDateTime": {
"S": "2023-02-13T18:14:52.143Z"
},
":subjectUpdateCounterLimit": {
"N": "0"
}
},
"ReturnValues": "NONE",
"ExpressionAttributeNames": {
"#subjectUpdateCounter": "SubjectUpdateCounter",
"#maths":"Maths"
}
}

Firestore Pagination: how to define 'startAt'-cursor for REST?

I am trying to use a cursor and 'startAt', to paginate REST requests to Firestore. According to the Paginate-documentation, the cursor should equal to the last document of the previous query. As the REST-documentation is without an example, I tried to run it by inserting an entire document as cursor in the startAt-object; like this:
POST https://firestore.googleapis.com/v1/PROJECT-NAME/databases/(default)/documents/organizations/testManyInstructions:runQuery
{
"structuredQuery": {
"from": [
{
"collectionId": "instructions"
}
],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "belongsToDepartementID"
},
"op": "EQUAL",
"value": {
"stringValue": "toplevel-document-id"
}
}
},
"orderBy": [
{
"field": {
"fieldPath": "instructionNumber"
},
"direction": "ASCENDING"
}
],
"startAt": {
"values": [{
"document": {
"name": "projects/PROJECT-NAME/databases/(default)/documents/organizations/testManyInstructions/instructions/i0",
"fields": {
"checkbox": {
"booleanValue": false
},
"retrainTimespanDays": {
"integerValue": "365000"
},
"approvedByName": {
"stringValue": ""
},
"instructionNumber": {
"stringValue": "instr. 0"
},
"instructionCurrentRevision": {
"stringValue": "A"
},
"instructionCurrentRevisionPublishingDate": {
"timestampValue": "1999-01-01T00:00:00Z"
},
"instructionFileURL": {
"stringValue": ""
},
"instructionTitle": {
"stringValue": "dummy Title0"
},
"instructionFileUploadDate": {
"timestampValue": "1999-01-01T00:00:00Z"
},
"belongsToDepartementID": {
"stringValue": "toplevel-document-id"
},
"approvedByEmailAdress": {
"stringValue": ""
}
},
"createTime": "2022-02-18T13:55:42.807103Z",
"updateTime": "2022-02-18T13:55:42.807103Z"
}
}
]
},
"limit": 5
}
}
without the "startAt"-Object, the following code works fine and returns 5 documents.
with the "startAt"-Object, this error is returned:
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"document\" at 'structured_query.start_at.values[0]': Cannot find field.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "structured_query.start_at.values[0]",
"description": "Invalid JSON payload received. Unknown name \"document\" at 'structured_query.start_at.values[0]': Cannot find field."
}
]
}
]
}
}
]
Please advise, how to set the cursor in the startAt-object correctly.
I've run a similar query using offset instead of startAt, so I tried modifying and got it to work. This is the rest api documentation I used.
startAt requires a Cursor object which is an array of Values.
https://firebase.google.com/docs/firestore/reference/rest/v1/StructuredQuery
https://firebase.google.com/docs/firestore/reference/rest/v1/Cursor
https://firebase.google.com/docs/firestore/reference/rest/Shared.Types/ArrayValue#Value
I would have preferred an example as well!
"startAt": {
"values": [{
"stringValue": "Cr"
}]
},
"orderBy": [{
"field": {
"fieldPath": "Summary"
}
}],
Good luck!

dynamodb UpdateItem using API Gateway as Proxy, error

I am using the AWS API Gateway as proxy to expose DynamoDB API. the UpdateItem mapping is not working, it return:
{
"__type": "com.amazon.coral.service#SerializationException"
}
Below is the mapping template and the payload:
{
"TableName": "registros",
"Key": {
"Pk": {
"S": "$input.path('$.Pk')"
},
"Sk": {
"S": "$input.path('$.Sk')"
}
},
"UpdateExpression": "set intenciones = :intenciones",
"ConditionExpression": "Pk = :Pk, Sk = :Sk,",
"ExpressionAttributeValues": {
":Pk": {"S": "$input.path('$.Pk')"},
":Sk": {"S": "$input.path('$.Sk')"},
":intenciones": {"S": "$input.path('$.intenciones')"},
},
"ReturnValues": "UPDATED_NEW"
}
Payload:
{
"Pk":"DemandaProd",
"Sk":"raerytre#22",
"intenciones":"news"
}
You don't need ConditionExpression since it's implied with Key that you'll be matching on the Pk and Sk. Try this:
{
"TableName": "registros",
"Key": {
"Pk": {
"S": "$input.path('$.Pk')"
},
"Sk": {
"S": "$input.path('$.Sk')"
}
},
"UpdateExpression": "set intenciones = :intenciones",
"ExpressionAttributeValues": {
":intenciones": { "S": "$input.path('$.intenciones')" }
},
"ReturnValues": "UPDATED_NEW"
}

I am not seeing dialogState in Alexa's event in AWS lambda logs, for a multiturn dialog?

I created an intent with slots in Alexa. This triggers an AWS lambda written in Python. I am logging the 'event'. I expect event['request']['dialogState'] to be present but it is not. Am I missing something?
Event:
{u'session': {u'application': {u'applicationId': u'amzn1.ask.skill.b2a191bb-7ee2-4fa7-aa7b-456d4bd2ee35'}, u'sessionId': u'Sessi onId.afb747ea-01ae-4094-ba10-ac49405a99df', u'user': {u'userId': u'amzn1.ask.account.BFHTSNCIVD2HA563BEPLRW5TSCESQEZXCIULPPB2ULOZBIJRCPM 5Z5NWOWH3HWNOZRTY4WT3FZFVGWWPKRSKC4ZNDSB2EYB45TYQ3RNY67CZPGF4GBMV6CL57C5MJVPIQPH25DQWGXGALDBCBRHMG5IA3Y26UHI7MHPIV3665ZU5OESS3UBADD7MDYQ BWJZFB3XHJS6IM2Y5UTQ', u'accessToken': None}, u'new': False, u'attributes': {}}, u'request': {u'locale': u'en-US', u'type': u'IntentRequ est', u'intent': {u'slots': {u'ncpu': {u'name': u'ncpu'}, u'nmem': {u'name': u'nmem'}}, u'name': u'CreateVM'}, u'requestId': u'EdwReques tId.c9de162a-d606-43a1-9257-b7367c9da5de', u'timestamp': u'2017-10-24T09:43:17Z'}, u'version': u'1.0', u'context': {u'AudioPlayer': {u'p layerActivity': u'IDLE'}, u'System': {u'device': {u'supportedInterfaces': {}}, u'application': {u'applicationId': u'amzn1.ask.skill.b2a1 91bb-7ee2-4fa7-aa7b-456d4bd2ee35'}, u'user': {u'userId': u'amzn1.ask.account.BFHTSNCIVD2HA563BEPLRW5TSCESQEZXCIULPPB2ULOZBIJRCPM5Z5NWOWH 3HWNOZRTY4WT3FZFVGWWPKRSKC4ZNDSB2EYB45TYQ3RNY67CZPGF4GBMV6CL57C5MJVPIQPH25DQWGXGALDBCBRHMG5IA3Y26UHI7MHPIV3665ZU5OESS3UBADD7MDYQBWJZFB3X HJS6IM2Y5UTQ'}}}}
You can not test you skills inside of the Amazon developer portal because these will not return a Dialogstate for your dialog. If you want to test your skill i suggest you go to echosim.io or get an echo dot to experiment with.
If you don't want to test with echosim.io or a real echo device and you have your skill code inside of AWS Lambda you can always test your code there with the test command.
Example:
{
"session": {
"new": true,
"sessionId": "SessionId.******************0ed735901",
"application": {
"applicationId": "amzn1.ask.skill.e96d9***********3ee1b958e6ca"
},
"attributes": {},
"user": {
"userId": "amzn1.ask.account.AGMQGVEZFE355BBMXYBQGFN7TRN5E5CSGUU5Y3AUNEBT3DOZ7IOQ3K7G3RGIOI7BEJVLVR4CWSARSTMAF5RNA4QW************DURTSESLYMYDVIQLWA2LF6PHG3KB3UEOLZWYBBWLRKCFFMG7JFP7TNKCS2RQ4KOGPIMOT2PGQT3S2HAOBNJSAA
}
},
"request": {
"type": "IntentRequest",
"dialogState": "IN_PROGRESS",
"requestId": "EdwRequestId.5b2a45f7-e4bb-44cd-ba9f-1cfe138d577f",
"intent": {
"name": "SearchIntent",
"slots": {
"AnswerTime": {
"name": "AnswerTime",
"value": "Nope"
},
"FirstTime": {
"name": "FirstTime",
"value": "02:00"
},
"SecondTime": {
"name": "SecondTime"
},
"Date": {
"name": "Date",
"value": "2017-10-20"
},
"Name": {
"name": "Name",
"value": "Liam De Lee"
}
}
},
"locale": "en-US",
"timestamp": "2017-10-19T13:29:17Z"
},
"context": {
"AudioPlayer": {
"playerActivity": "IDLE"
},
"System": {
"application": {
"applicationId": "amzn1.ask.skill.e96d95e0-8cbd-41d2-a280-3ee1b958e6ca"
},
"user": {
"userId": "amzn1.ask.account.AGMQGVEZFE355BBMXYBQGFN7TRN5E5CSGUU5Y3AUNEBT3DOZ7IOQ3K7G3RGIOI7BEJVLVR4CWSARSTMAF5RNA4QW************DURTSESLYMYDVIQLWA2LF6PHG3KB3UEOLZWYBBWLRKCFFMG7JFP7TNKCS2RQ4KOGPIMOT2PGQT3S2HAOBNJSAA"
},
"device": {
"supportedInterfaces": {}
}
}
},
"version": "1.0"
}
Note: Service Simulator does not currently support testing audio
player directives, dialog model, customer permissions and customer
account linking.
Amazon developer portal.

DynamoDB UpdateException: Type mismatch for attribute to update

I have the following record in DynamoDB:
{
"BusinessNo": {
"N": "12345"
},
"Metadata": {
"M": {
"MimeType": {
"S": "audio/wav"
},
"FileName": {
"S": "00032329.wav"
},
"CustomC": {
"S": "baz"
},
"CustomA": {
"S": "foo"
},
"CustomB": {
"S": "bar"
},
"Size": {
"S": "3992020323"
}
}
},
"Id": {
"S": "f0de8af3-a7f5-4d9b-ad5d-b2f150abd15e"
},
"Revision": {
"N": "2"
}
}
But when I submit the following using the update method of DynamoDB.DocumentClient from the nodejs AWS SDK (I have also tried add instead of set):
{
"TableName": "Storage_FileMetadata",
"Key": {
"Id": "f0de8af3-a7f5-4d9b-ad5d-b2f150abd15e",
"BusinessNo": "12345"
},
"ExpressionAttributeNames": {
"#m": "Metadata",
"#k": "CustomD",
"#r": "Revision"
},
"ExpressionAttributeValues": {
":r": 4,
":v": "doo-wop"
},
"UpdateExpression": "set #m.#k = :v",
"ConditionExpression": "#r < :r"
}
I get the following exception:
{
"message": "Type mismatch for attribute to update",
"code": "ValidationException",
"time": "2016-11-11T18:55:01.543Z",
"requestId": "b9d78c87-1c4d-400a-8968-d761b657cd53",
"statusCode": 400,
"retryable": false,
"retryDelay": 0
}
I think I'm missing something about adding/updating nested attributes but after reading the docs I can't figure out what.
Seems that you need to send the value "BusinessNo": "12345" as a number
"Key": {
"Id": "f0de8af3-a7f5-4d9b-ad5d-b2f150abd15e",
"BusinessNo": 12345
}

Resources