Skip to content

Instantly share code, notes, and snippets.

@ArsenyYankovsky
Last active December 2, 2023 02:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArsenyYankovsky/1d189123b97ea692f1cf8be152bc1d45 to your computer and use it in GitHub Desktop.
Save ArsenyYankovsky/1d189123b97ea692f1cf8be152bc1d45 to your computer and use it in GitHub Desktop.
Lock an item in DynamoDB for exclusive processing.
/*
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