Search code examples
mongodbspring-bootredisspring-data-redis

How to leverage redis and mongo in the following scenario?


I am using the change streams to keep the redis cache up to date whenever a change happens in the mongodb. I am updating the cache in two steps whenever the db is changed:

  1. clear cache
  2. Load data from scratch

code:

redisTemplate.delete(BINDATA);
redisTemplate.opsForHash().putAll(BINDATA, binDataItemMap);

The problem is that in prod this setting may be dangerous. As redis is single threaded there is the chance the events will happen in the following way in a multi-container application:

  1. db update happens
  2. data is cleared in redis
  3. request comes in and queries an empty redis cache
  4. data is pushed into redis

Ideally it should happen as so:

  1. db update happens
  2. data is cleared in redis
  3. data is pushed into redis
  4. request comes in and queries an updated redis cache

How can both operations clear and update happen in redis as a block?


Solution

  • Redis supports a kind of transactions. This fits exactly your needs.

    All the commands in a transaction are serialized and executed sequentially. It can never happen that a request issued by another client is served in the middle of the execution of a Redis transaction. This guarantees that the commands are executed as a single isolated operation.

    A Redis transaction is entered using the MULTI command. At this point the user can issue multiple commands. Instead of executing these commands, Redis will queue them. All the commands are executed once EXEC is called.

    Pseudo Code:

    > MULTI
    OK
    > redisTemplate.delete(BINDATA);
    QUEUED
    > redisTemplate.opsForHash().putAll(BINDATA, binDataItemMap);
    QUEUED
    > EXEC