Last active
December 2, 2023 02:11
-
-
Save ArsenyYankovsky/1d189123b97ea692f1cf8be152bc1d45 to your computer and use it in GitHub Desktop.
Lock an item in DynamoDB for exclusive processing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Assuming you have a blog Posts table with the following structure: | |
{ | |
// hash key | |
"id": 154325, | |
"title": "Things you need to know before going bouldering for the first time.", | |
"text": "...", | |
// represents unix time of a moment this record was locked at | |
"lockedAt": 1684067555 | |
} | |
*/ | |
import { DynamoDBClient, UpdateItemCommand } from '@aws-sdk/client-dynamodb' | |
const example = async () => { | |
const client = new DynamoDBClient({ region: 'eu-west-1' }) | |
// Lock the item for 5 minutes, usually you should only lock for your lambda's timeout | |
const lockFor = 300_000 | |
const now = Date.now() | |
const postId = '154325' | |
// Will lock a record or throw a ConditionalCheckFailedException if it's already locked | |
const result = await client.send(new UpdateItemCommand({ | |
"TableName": "posts", | |
"ReturnValues": "ALL_NEW", | |
"Key": { | |
"id": { | |
"N": postId | |
} | |
}, | |
"ConditionExpression": "(attribute_exists(#id)) AND ((#lockedAt = :null) OR (#lockedAt <= :lockExpiredAt))", | |
"UpdateExpression": "SET #lockedAt = :now", | |
"ExpressionAttributeNames": { | |
"#id": "id", | |
"#lockedAt": "lockedAt" | |
}, | |
"ExpressionAttributeValues": { | |
":null": { | |
"NULL": true | |
}, | |
":lockExpiredAt": { | |
"N": (now - lockFor).toString() | |
}, | |
":now": { | |
"N": now.toString() | |
} | |
} | |
})) | |
try { | |
// Do some processing | |
} finally { | |
// Unlock the record | |
await client.send(new UpdateItemCommand({ | |
"TableName": "posts", | |
"ReturnValues": "ALL_NEW", | |
"Key": { | |
"id": { | |
"N": postId | |
} | |
}, | |
"UpdateExpression": "SET #lockedAt = :null", | |
"ExpressionAttributeNames": { | |
"#lockedAt": "lockedAt" | |
}, | |
"ExpressionAttributeValues": { | |
":null": { | |
"NULL": true | |
}, | |
} | |
})) | |
} | |
} | |
example() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment