Reputation: 2241
I'm creating a new item in DynamoDB and I want it to throw an exception if the hash key already exists. I want this, because I don't want to have to query for an item before the insert for performance reasons, as it is extremely unlikely that my key will collide. but if it does i want to retry with a new key. Currently when I call Save via the object level api, it just updates the record.
public class DynamoService
{
private readonly IDynamoDBContext _dbContext;
private readonly IAmazonDynamoDB _dynamoClient;
public DynamoService(IAmazonDynamoDB dynamoClient, IDynamoDBContext dbContext )
{
_dynamoClient = dynamoClient;
_dbContext = dbContext;
}
public virtual async Task Save<T>(T item) where T : new()
{
await _dbContext.SaveAsync(item);
}
}
Upvotes: 4
Views: 2098
Reputation: 364
This is also possible with the .NET Object Persistence model by using "Optimistic Locking" (described here)
Inside your class you have to mark one property for being used as a VersionNumber
.
public class DynamoDbItem
{
[DynamoDBHashKey]
public string SomeId { get; set; }
// https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBContext.VersionSupport.html
[DynamoDBVersion]
public int? VersionNumber { get; set; }
}
During saving you need to specify that you want to perform a version check.
public virtual async Task Save<T>(T item) where T : new()
{
await _dbContext.SaveAsync(item, new DynamoDBOperationConfig
{
SkipVersionCheck = false
});
}
For creating the item (saving for the first time) set the VersionNumber = null
. The item will be saved in DynamoDB with VersionNumber = 0
. Then if you try to create an item with the same PrimaryKey (and SortKey) VersionNumber = null
(from C#) will not match VersionNumber = 0
(saved in DynamoDB) and SaveAsync
will throw an exception.
Note: This only works if you specify SkipVersionCheck = false
either as DynamoDBOperationConfig
or as DynamoDBContextConfig
on _dbContext
.
Upvotes: 1
Reputation: 3035
Add a conditional expression using attribute_not_exists
to your PutItem request.
See the section "Preventing Overwrites of an Existing Item" in https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html
The conditional expression will cause a ConditionalCheckFailedException
if the item already exists, which you can catch and then do your retry logic
Upvotes: 1