Мы используем транзакции Ignite в режиме READ_COMMITED, а также используем шаблон проектирования Optimistic Offline Lock для соответствия требованиям согласованности данных и задержкам при чтении. Для нашего бизнеса важно не видеть частично обновленные данные в кеше во время чтения. REPEATABLE_READ блокирует чтение, поэтому мы не используем его.
Транзакция чтения:
@Override
public SearchResult apply(ComputeTaskInData<SearchProductOffer> data) {
while (true) {
try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, READ_COMMITTED)) {
Long initialTimestamp = getCurrentTimestampFromIgniteCache();
... // multiple caches read where we can see commited data in the middle of read
Long finalTimestamp = getCurrentTimestampFromigniteCache();
// Check if transaction was commited in the middle of read request. If so, retry. This
timestamp increments in update transaction.
if (finalTimestamp > initialTimestamp) continue;
return readResult;
}
}
Транзакция обновления:
try (Transaction transaction = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {
// Multiple caches update.
IgniteCache<OfflineLockKey, Long> offerOfflineLock =
ignite.getOrCreateCache(OFFLINE_LOCK.name());
OfflineLockKey offlineLockKey = new
OfflineLockKey(segmentIndex.segmentInfo.getSegmentId());
Long offerTimestamp = offerOfflineLock.get(offlineLockKey);
if (offerTimestamp == null) {
offerTimestamp = 0L;
}
offerTimestamp++;
offerOfflineLock.put(offlineLockKey, offerTimestamp);
transaction.commit();
}
Но проблема в том, что мы читаем противоречивые данные и не повторяем попытки. Кажется, что транзакция зажигания не является атомарной, и мы не получаем увеличенную временную метку. Предполагается ли поведение в режиме PESSIMISTIC READ_COMMITED? Мы пробовали разные режимы кеширования для кеша offline_lock. И да, все кэши являются транзакционными.