# @CacheEvict runs after the method - unless you ask otherwise

price("sku-1") -> 100   (stored price is 100)

updatePrice("sku-1", 250, fail=true) threw after writing the new price.
stored price now  : 250
price("sku-1")    : 100   <- the cache still serves the old value
reads of the real store: 1

--- beforeInvocation = true ---
price("sku-2") -> 100
updatePriceEvictFirst("sku-2", 250, fail=true) threw the same way.
price("sku-2")    : 250   <- the entry went first, so the next read is honest

--- @CachePut instead: write through, no miss ---
after @CachePut, price("sku-3") -> 400
reads of the real store: 1 -> 1   <- no reload was needed
