Sitemap

Lock Implementation in AWS DynamoDB with Golang

2 min readOct 27, 2024

--

Introduction

I write about how to implement lock in S3 the below article. In this article, I’d like to introduce implementing locks for AWS DynamoDB.

Condition Expressions

DynamoDB provides a way to update with conditional. This makes it easy to update the specified item easily. In this scenario, we will use this function to judge should we get the lock.

Implement locking in DynamoDB

If you are using AWS SDK v2, the implementation is as follows.

now := time.Now().Unix()
lockExpiresAt := time.Now().Add(time.Duration(lockTimeout) * time.Second).Unix()

input := &dynamodb.UpdateItemInput{
TableName: aws.String(tableName),
Key: map[string]types.AttributeValue{
lockIDAttr: &types.AttributeValueMemberS{Value: lockID},
},
UpdateExpression: aws.String(fmt.Sprintf("SET %s = :expiresAt", lockExpiresAttr)),
ConditionExpression: aws.String(fmt.Sprintf(
"attribute_not_exists(%s) OR %s <= :now",
lockIDAttr, lockExpiresAttr)),
ExpressionAttributeValues: map[string]types.AttributeValue{
":expiresAt": &types.AttributeValueMemberN{Value: fmt.Sprintf("%d", lockExpiresAt)},
":now": &types.AttributeValueMemberN{Value: fmt.Sprintf("%d", now)},
},
}

_, err := svc.UpdateItem(ctx, input)
if err != nil {
return fmt.Errorf("failed to acquire lock: %w", err)
}

The key to this implementation is the ConditionExpression method. This checks whether the lockID exists and if the expiration time has already passed. The attribute_not_exists function checks if the item exists. Additionally, the expiresAt attribute is compared to the current time to ensure it has passed. To perform this comparison, we must store the expiration time in expiresAt as a Unix timestamp.

Reference

--

--

No responses yet