在读取提交模式下点燃事务不一致

时间:2019-10-23 10:08:22

标签: transactions ignite

我们在READ_COMMITED模式下使用Ignite事务,并且还使用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缓存尝试了不同的缓存模式。 是的,所有缓存都是TRANSACTIONAL。

1 个答案:

答案 0 :(得分:0)

我这边的问题是缓存配置。

您必须使用该配置获取缓存(在我的情况下,这是我的本地缓存)

     ingite.getOrCreateCache(new CacheConfiguration("cacheName")
                    .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)
                    .setCacheMode(CacheMode.LOCAL));