Let's say we have an app where the users gain points and can exchange them for rewards. The *exchange* request, in pseudo-code, could look like this:

```
function exchangePointsForReward(userId, rewardId){
    user = getUser(userId)
    reward = getReward(rewardId)
    if (user.points >= reward.requiredPoints){
        giveRewardToUser(userId, rewardId)
        reduceUserPoints(userId, reward.requiredPoints)
    }
}

```

But if we have a malicious user what stops them from crafting a request in their favorite programming language and sending it 20 times at the same time? Before the first request reaches `reduceUserPoints()` ten other might've already got as far as `addNewReward()`. Sure, the user's points at the end of the day might go deep into negative, but what stops the user from quickly grabbing the rewards and using them up? **How can I ensure that only one operation can be executed for a user at the same time?**

One solution I can think of is the operation tries to acquire a lock at the beginning of the operation and only a single lockable operation can run for a user at any moment:

```
function aquireLock(userId){
    lockId = getRandomLockId()
    database.query("UPDATE user SET lock={lockId} WHERE user={userId} AND lock IS NULL");
    return database.query("SELECT lock WHERE user = {userId}").first === lockId;
}

function exchangePointsForReward(userId, rewardId){
    if (!aquireLock(userId)){
        throw new Error("Failed to acquire lock");
    }
    user = getUser(userId)
    reward = getReward(rewardId)
    if (user.points >= reward.requiredPoints){
        giveRewardToUser(userId, rewardId)
        reduceUserPoints(userId, reward.requiredPoints)
    }
    releaseLock(userId);
}

```

But is there any better strategy here? The question is database-agnostic.