Reputation: 9234
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
Reputation: 31528
A few things to note :
INCR
and INCRBY
commands will create the key if it doesn't already existsSo, 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