redisson / redisson

Redisson - Easy Redis Java client and Real-Time Data Platform. Valkey compatible. Sync/Async/RxJava/Reactive API. Over 50 Redis or Valkey based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Spring, Tomcat, Scheduler, JCache API, Hibernate, RPC, local cache...
https://redisson.pro
Apache License 2.0
23.29k stars 5.34k forks source link

How to set TTL on read-through cache #4909

Open DanilDelegator opened 1 year ago

DanilDelegator commented 1 year ago

I"m trying to set a Redisson distributed cache with a read-through cache using MapLoader.

There is no apparent way to set the TTL on values that get injected using the MapLoader. Example (from wiki):

        MapLoader<String, String> mapLoader = new MapLoader<String, String>() {

            @Override
            public Iterable<String> loadAllKeys() {
                List<String> list = new ArrayList<String>();
                Statement statement = conn.createStatement();
                try {
                    ResultSet result = statement.executeQuery("SELECT id FROM student");
                    while (result.next()) {
                        list.add(result.getString(1));
                    }
                } finally {
                    statement.close();
                }

                return list;
            }

            @Override
            public String load(String key) {
                PreparedStatement preparedStatement = conn.prepareStatement("SELECT name FROM student where id = ?");
                try {
                    preparedStatement.setString(1, key);
                    ResultSet result = preparedStatement.executeQuery();
                    if (result.next()) {
                        return result.getString(1);
                    }
                    return null;
                } finally {
                    preparedStatement.close();
                }
            }
        };
MapOptions<K, V> options = MapOptions.<K, V>defaults()
                              .loader(mapLoader);

RMapCache<K, V> map = redisson.getMapCache("test", options);

Now that this is set-up I can use it like this:

println(map["1234"]) // loader loads 1234 into redis
// Let's say the values change in the DB
println(map["1234"]) // loader does not load 1234 as it is already in redis. The value is forever incorrect.
DanilDelegator commented 1 year ago

I believe the main problem is that MapOption passed to getMapCache assumes a write-through|behind strategy where a TTL is not a must.