stephen776
stephen776

Reputation: 9234

How to use ServiceStack CacheClient and Redis to increment or create counters

I am using ServiceStacks CacheClient and Redis libraries. I want to cache counts of the number of certain transactions that users perform. I am using the following to GET the cached value or create it from the DB if the key does not exist:

public int GetTransactionCountForUser(int userID)
{
    int count;

    //get count cached in redis...
    count = cacheClient.Get<int>("user:" + userID.ToString() + ":transCount");

    if (count == 0)
    {
        //if it doent exists get count from db and cache value in redis
        var result = transactionRepository.GetQueryable();
        result = result.Where(x => x.UserID == userID);
        count = result.Count();

        //cache in redis for next time...
        cacheClient.Increment("user:" + userID.ToString() + ":transCount", Convert.ToUInt32(count));
    }

    return count;
}

Now, in another operation(when the transaction occurs) I will add a row to the DB and I would like to increment my Redis counter by 1.

Do I first need to check to see if the particular key exists before incrementing? I know that the Increment method of cache client will create the record if it does not exists, but in this case the counter would start at 0 even if there are transaction records in the DB.

What is the proper way to handle this situation? Get key, if null, query db to get count and create the key with this number?

Upvotes: 3

Views: 1594

Answers (1)

Sripathi Krishnan
Sripathi Krishnan

Reputation: 31528

A few things to note :

  1. You can use the EXISTS to check if the key already exists. This is better because you can now cache users that actually have 0 transactions.
  2. INCR and INCRBY commands will create the key if it doesn't already exists

So, in pseudo code, here's what you should do -

if EXISTS user:<userid>:transcount
    return GET user:<userid>:transcount
else
    int transCountFromDB = readFromDB();
    INCRBY user:<userid>:transcount transCountFromDB
    return transCountFromDB

You may also want to execute an EXPIRE command on the key right after you do INCRBY, so that you only cache records for an acceptable time.

Upvotes: 2

Related Questions