Один из подходов заключается в том, чтобы иметь глобальный счетчик обновлений в базе данных, либо для обновлений, либо для чтения (обновления более эффективны, но и сложнее получить правильные данные).
Таким образом, при каждом обновлении также увеличивайте глобальный счетчик. При каждом чтении считывайте глобальный счетчик и помещайте данные в кэш вместе со значением счетчика. Перезаписывать содержимое кэша только в том случае, если значение счетчика больше.
Из-за изоляции базы данных транзакции должны выглядеть так, как если бы они происходили последовательно (при условии, что вы выбрали уровень изоляции SERIALIZABLE). Это, в свою очередь, будет означать, что строго более высокие значения счетчиков относятся к более поздним данным.