Список кэширования Spring и обновление его значений

Я создаю приложение Spring, которое сохраняет в базе данных Postgres GPS-позиции транспортных средств. Транспортные средства отправляют свое местоположение каждую минуту. Каждое транспортное средство идентифицируется некоторым идентификатором (String). Существует конечная точка REST для получения всех текущих позиций. Я хотел бы кэшировать все текущие позиции GPS, чтобы ускорить их получение без запроса базы данных.

Я пытался использовать:

@Cacheable(key = "'all'")
List<Position> getAllVehiclePositions();

и это работает, но проблема в том, что когда какое-то транспортное средство отправляет новую позицию, у меня нет возможности обновить список в кеше, поэтому я должен

@CacheEvict(key = "'all'")

что не имеет никакого смысла, потому что кеш все еще вытесняется.

Я читал об этом, например. https://jira.spring.io/browse/SPR-12036, но есть нет решения (только не использовать кеш).

Я подумал о создании ConcurrentHashMap, где ключом будет идентификатор транспортного средства, чтобы я мог легко обновлять его, и я мог просто использовать потоки для преобразования списка в карту.

Что я должен делать? Какое лучшее решение?


person user3626048    schedule 02.01.2017    source источник


Ответы (2)


Я бы рассмотрел 2 варианта в зависимости от того, насколько актуальным должен быть ответ.

Вариант 1: @Cacheable + TTL

Если вам не нужны абсолютно свежие ответы, вы можете просто использовать аннотацию @Cacheable и настроить кеш на значение TTL 30 секунд, 1 минуту или любое другое значение, подходящее для вашего приложения. Преимущество этого заключается в том, что вам не нужно беспокоиться о заполнении кеша и вытеснении его из вашего бизнес-кода за счет обслуживания потенциально устаревших данных (но вы контролируете, насколько они устарели).

Вариант 2: ConcurrentHashMap + пользовательская логика обновления кеша

Если вам всегда нужны самые свежие данные, я бы посоветовал вам использовать ConcurrentHashMap, чтобы поддерживать его в актуальном состоянии в базе данных. Преимущество этого заключается в том, что последние данные доступны за счет необходимости реализации заполнения и вытеснения кэша.

person cjungel    schedule 02.01.2017

Я думаю, вы можете использовать аннотацию @CachePut. См.: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html#cache-annotations-put

что вы можете сделать, кроме обычного метода обновления, создайте второй метод для обновления списка всех позиций следующим образом:

public Position updatePosition(...){
    ...
    updateAllPositions(...) 
}

@CachePut(key="'all'") 
public List<Position> updateAllPositions(...){
    ... 
}
person Selim Ok    schedule 02.01.2017
comment
но как это реализовать? - person user3626048; 02.01.2017