Ваше решение имеет две проблемы:
- Вы выполняете последовательное сканирование для сохранения, которое будет дорогостоящим при большом количестве записей
- Код имеет условия гонки
- Из-за условий гонки код не удовлетворяет вашим требованиям.Можно создать последовательность одновременного доступа, когда запись удаляется из кэша, но также записывается в базу данных
Существует ли какая-либо существующая инфраструктура технологии / spring / apache, которая уже предлагает такиекеш?(sidenote: я не хочу использовать сложные библиотеки, такие как redis, ehcache и т. д. для такого простого варианта использования).
Я думаю, что вы можете решить проблемы параллелизма на основе ConcurrentHashMap
.Но я не знаю элегантного способа для тайм-аута.Тем не менее, возможное решение - использовать библиотеку кеширования.Я хотел бы предложить пример, основанный на cache2k , который не тяжелый (около 400 тыс. Jar), а также имеет другие хорошие варианты использования.В качестве дополнения также существует хорошая поддержка абстракции кэширования Spring.
public static class WriteBehindCache {
Cache<String, Object> cache = Cache2kBuilder.of(String.class, Object.class)
.addListener((CacheEntryExpiredListener<String, Object>) (cache, entry)
-> persist(entry.getKey(), entry.getValue()))
.expireAfterWrite(60, TimeUnit.SECONDS)
.build();
public void add(String key, Object data) {
cache.put(key, data);
}
public Object get(String key) {
return cache.invoke(key, e -> {
if (e.exists()) {
Object v = e.getValue();
e.remove();
return v;
}
return loadAndRemove(e.getKey());
});
}
// stubs
protected void persist(String key, Object value) {
}
protected Object loadAndRemove(String key) {
return null;
}
}
При таком подключении кеш блокирует параллельную операцию с одной записью, поэтому можно с уверенностью сказать, что для одной записи выполняется только одна операция базы данных.время.
Вы можете сделать это аналогично другим библиотекам кэширования.При использовании API JCache / JSR107 код выглядел бы почти идентично.
Более "легкий" подход - использовать expiringmap
от jhalterman. Лично я считаю, что кэш должен бытьв каждом наборе инструментов для разработчиков.Тем не менее, я являюсь автором cache2k.Конечно, я должен это сказать.