I have a table has below schema:
UserId(hashkey), earnedPoints, status
I want to achieve: At any given time, for the same seller, he/she should only have 1 PENDING status record. Example:
user1, 10, PENDING
-> successful, as db dose not have record for user1user1, 30, PENDING
-> condition fail, as db already contain user1 record and that record is in PENDING status.user2, 10, REDEEMED
-> successful, as db dose not have record for user2user2, 10, PENDING
-> successful, db has record for user2, but that record is in status of REDEEMED, so inserting PENDING record is allowed.Try to use DDB Expression: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html to achieve this during putItem
operation, using software.amazon.awssdk.enhanced
client.
So I wrote:
Expression conditionExpression = Expression.builder()
.expression("attribute_not_exists(userId) OR #currentStatus <> :pendingStatus")
.putExpressionName("#currentStatus", "status")
.putExpressionValue(":pendingStatus",
AttributeValue.builder()
.s("PENDING")
.build())
.build();
Does not work.
Any suggestions?
Your issue is because DynamoDB does not evaluate the entire database when you put a condition on an attribute, it only evaluates the item you are operating on. So the condition is happening on completely different items.
You will need to make use of transactions to ensure global uniqueness as defined in this blog post: