Skip to content

@CacheEvict(allEntries=true) may delete newly inserted keys when beforeInvocation=false #36806

@FULaBUla

Description

@FULaBUla

When using Spring Cache with Redis, we observed a potential issue with @CacheEvict(allEntries=true) in combination with @CachePut that leads to intermittent deletion of newly inserted keys.

Environment:

  • Spring Boot: 4.0.6
  • Redis: 8.6.2
  • Redis: single node, TTL=-1 for all keys, non-clustered, single instance
  • CacheWriter: default non-locking RedisCacheWriter
  • Method visibility: public
  • @CachePut return values are never null
  • No transactions involved (@Transactional removed)

Steps to Reproduce:

  1. Define an empty @CacheEvict method on a cacheName:
@CacheEvict(cacheNames = "xxx", allEntries = true)
public void clearCache() {}
  1. Call clearCache() and then insert multiple items using @CachePut:
clearCache();
putCache(item1);
putCache(item2);
  1. Use redis-cli MONITOR to track commands.

Observed Behavior:

  • With beforeInvocation=false (default), the command sequence may be:
keys cacheName::*
set cacheName::item1 ...
unlink keys_from_snapshot
set cacheName::item2 ...
  • The UNLINK command may asynchronously delete the newly inserted first item, causing it to disappear.

  • This behavior occurs intermittently.

  • When beforeInvocation=true, the command sequence becomes:

keys cacheName::*
del keys_from_snapshot
set cacheName::item1 ...
set cacheName::item2 ...
  • In this case, all newly inserted items are preserved.

Questions:

  • Why are the values of beforeInvocation being changed using two different instructions, namely DEL and UNLINK??
  • Mechanically speaking, how exactly does UNLINK get inserted into the middle of the SET command for execution?
  • Is this behavior documented or expected, and should beforeInvocation=true be recommended whenever using allEntries=true with Redis and non-locking CacheWriter?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions