/** * 抖音关注:程序员三丙 * 知识星球:https://t.zsxq.com/j9b21 */ package sanbing.jcpp.infrastructure.cache; import java.io.Serializable; import java.util.Collection; import java.util.List; import java.util.function.Function; import java.util.function.Supplier; public interface TransactionalCache { String getCacheName(); CacheValueWrapper get(K key); void put(K key, V value); void putIfAbsent(K key, V value); void evict(K key); void evict(Collection keys); void evictOrPut(K key, V value); CacheTransaction newTransactionForKey(K key); CacheTransaction newTransactionForKeys(List keys); default V getOrFetchFromDB(K key, Supplier dbCall, boolean cacheNullValue, boolean putToCache) { if (putToCache) { return getAndPutInTransaction(key, dbCall, cacheNullValue); } else { CacheValueWrapper cacheValueWrapper = get(key); if (cacheValueWrapper != null) { return cacheValueWrapper.get(); } return dbCall.get(); } } default V getAndPutInTransaction(K key, Supplier dbCall, boolean cacheNullValue) { return getAndPutInTransaction(key, dbCall, Function.identity(), Function.identity(), cacheNullValue); } default R getAndPutInTransaction(K key, Supplier dbCall, Function cacheValueToResult, Function dbValueToCacheValue, boolean cacheNullValue) { CacheValueWrapper cacheValueWrapper = get(key); if (cacheValueWrapper != null) { V cacheValue = cacheValueWrapper.get(); return cacheValue != null ? cacheValueToResult.apply(cacheValue) : null; } var cacheTransaction = newTransactionForKey(key); try { R dbValue = dbCall.get(); if (dbValue != null || cacheNullValue) { cacheTransaction.put(key, dbValueToCacheValue.apply(dbValue)); cacheTransaction.commit(); return dbValue; } else { cacheTransaction.rollback(); return null; } } catch (Throwable e) { cacheTransaction.rollback(); throw e; } } default R getOrFetchFromDB(K key, Supplier dbCall, Function cacheValueToResult, Function dbValueToCacheValue, boolean cacheNullValue, boolean putToCache) { if (putToCache) { return getAndPutInTransaction(key, dbCall, cacheValueToResult, dbValueToCacheValue, cacheNullValue); } else { CacheValueWrapper cacheValueWrapper = get(key); if (cacheValueWrapper != null) { var cacheValue = cacheValueWrapper.get(); return cacheValue == null ? null : cacheValueToResult.apply(cacheValue); } return dbCall.get(); } } }