Class WriteThroughCacheStore

java.lang.Object
com.loomcache.springboot.persistence.WriteThroughCacheStore

public class WriteThroughCacheStore extends Object
Write-Through Cache Store.

Every cache write (PUT, DELETE) is synchronously persisted to the database via Spring Data JPA BEFORE the cache operation returns to the client.

  • Constructor Details

    • WriteThroughCacheStore

      public WriteThroughCacheStore(CacheEntryRepository repository, String nodeId, int instanceNumber)
      Construct the write-through cache store.
      Parameters:
      repository - the cache entry repository (not null)
      nodeId - the node identifier (not null)
      instanceNumber - the instance number for logging
  • Method Details

    • store

      @Transactional public void store(String mapName, String key, @Nullable Object value)
      Write-through: persist a cache entry to the database. Called synchronously on every PUT.
    • delete

      @Transactional public void delete(String mapName, String key)
      Delete-through: remove a cache entry from the database. Called synchronously on every DELETE.
    • load

      @Transactional(readOnly=true) public @Nullable String load(String mapName, String key)
      Load a value from the database (read-through / warm-up). Returns null if not found.
    • loadAll

      @Transactional(readOnly=true) public Map<String,String> loadAll(String mapName)
      Load all entries for a map (full cache warm-up) using paginated queries.

      Entries are loaded in pages of 1000 to prevent OOM when millions of entries exist in the database.

      Recovery-envelope contract: if the persisted row count exceeds LOAD_ALL_MAX_ENTRIES we throw IllegalStateException rather than silently truncating — a partial recovery would return a node to service with missing data, which operators must never receive as "healthy". Either raise the cap, shard the map, or remove persisted rows before restart.

      Fail-closed on DB errors: a DataAccessException raised mid-iteration is rethrown as LoomException rather than silently returning the partial page set collected so far. Returning a partial map would warm the cache with an arbitrary subset of keys — subsequent reads for the missing keys would miss and re-fetch from origin (best case) or return null for keys that do exist in the DB (worst case). Both are silent correctness failures. Propagating aborts node warm-up, which is the same posture as the row-count cap above.

    • clearAll

      @Transactional public void clearAll(String mapName)
      Clear all persisted entries for a map.
    • count

      @Transactional(readOnly=true) public long count(String mapName)
      Count persisted entries for a map.