java.lang.IllegalStateException: не удалось начать новую транзакцию (текущий поток уже имеет транзакцию - PullRequest
0 голосов
/ 18 апреля 2019

В транзакционном подходе в кешах Ignite мы используем многопоточный подход.

вариант 1: несколько потоков вставляются в кэш (без блокировки) для одного и того же ключа.

вариант 2: несколько потоков считывают данные из кэша (в транзакционной блокировке) с одинаковым ключом.

В случае 2 мы получаем ошибку, указанную ниже,

java.lang.IllegalStateException: не удалось начать новую транзакцию (текущий поток уже имеет транзакцию): GridNearTxLocal [mappings = IgniteTxMappingsImpl [], nearLocallyMapped = false, colocatedLocallyMapped = false, needCheckBackup = null, hasRemoteLocks = true, trackTimeout = false, lb = null, mvccTracker = null, mvccOp = null, thread = работник запуска задачи исполнителя для задачи 290, mappings = IgniteTxMappingsImpl [], super = GridDhtTxLocalAdapter [nearOnOriginatingNode = false, nearNodes = [], dhtNodes = [], licitLock = false, super = IgniteTxLocalAdapter [completeBase = null, sndTransformedVals = false, depEnabled = false, txState = IgniteTxStateImpl [activeCacheIds = [105038815], recovery = false, mvccEnabled = false, txMap = [IgniteTxEntry [key = KeyCacheObjectImpl [part = 344, val = abc, hasValBytes = false], cacheId = 105038815, txKey = IgniteTxKey [key = KeyCacheObjectImpl [part = 344, val = abc, hasValBytes = false], cacheId = 105038815], val = [op = READ, val = null], prevVal = [op = NOOP, val = null], oldVal = [op = NOOP, val = null], entryProcessorsCol = null, ttl = -1, конфликтExpireTime = -1, конфликтVer = ноль, явныйВер = ноль, dhtVer = null, filters = null, filtersPassed = false, filtersSet = true, entry = GridDhtDetachedCacheEntry [super = GridDistributedCacheEntry [super = GridCacheMapEntry [key = KeyCacheObjectImpl [part = 344, val = abc, hasValBytes = false], val = null, ver = GridCacheVersion [topVer = 166176849, order = 1554721151514, nodeOrder = 1], hash = -1768407104, extras = null, flags = 0]]], подготовлено = 0, заблокировано = true, nodeId = 962ec8e9-c7bd-4b73-b4d3-078da58f4439, locMapped = false, expiryPlc = null, TransferExpiryPlc = false, flags = 0, partUpdateCntr = 0, serReadVer = null, xidVer = GridCacheVersion [topVer = 166176849, order = 1554721151514, nodeOrder = 44]]]], mvccWaitTxs = null, qryEnlisted = false, forceSkipCompletedVers = false, super = IgniteTxAdapter [xidVer = GridCacheVersion [topVer = 166176849, заказ = 1554721151514, nodeOrder = 44], writeVer = null, неявный = false, loc = true, threadId = 3770, startTime = 1554721555785, nodeId = 6fb5bb88-fc57-478e-9fb9-c26cc8a311e8, startVer = GridCacheVersion [topVer = 166176849, заказ = 1554721151514, nodeOrder = 44], endVer = null, изоляция = REPEATABLE_READ, параллелизм = PESSIMISTIC, тайм-аут = 0, sysInvalidate = false, sys = false, plc = 2, commitVer = null, финализация = NONE, invalidParts = null, state = ACTIVE, timedOut = false, topVer = AffinityTopologyVersion [topVer = 44, minorTopVer = 0], txCounters = ноль, длительность = 156 мс, onePhaseCommit = false], size = 1]]]

Фрагмент кода, как показано ниже,

IgniteCache<String, String> cache =  ignite.getOrCreateCache("ABC_CACHE");
Transaction tx = ignite.transactions().txStart(TransactionConcurrency.PESSIMISTIC, TransactionIsolation.REPEATABLE_READ);

String acknowledge = cache.get(key);
if(acknowledge == null || acknowledge.length() == 0) {
if(acknowledge.contains("xyz")) {
    acknowledge.append("mln");
}
    flag = true;
    cache.removeAsync(key);
}else {
    cache.putAsync(key, acknowledge);
}
tx.commit();
tx.close();

Кроме того, при использовании уровня изоляции READ_COMMITTED ошибка не возникла, но не удалось добиться блокировки транзакции. Может кто-нибудь объяснить, где я ошибаюсь?

1 Ответ

1 голос
/ 19 апреля 2019

Возможно, вам не удалось закрыть какую-либо транзакцию.

Я рекомендую открыть транзакцию в try() предложении, а close() в finally{}

...