【发布时间】:2019-04-18 11:08:45
【问题描述】:
在 Ignite 缓存中的事务方法中,我们使用多线程方法。
案例 1:多个线程在同一个键上插入缓存(无锁定)。
案例 2:多个线程从缓存中读取数据(在事务锁定中)使用相似的键。
对于案例 2,我们遇到了下面提到的错误,
java.lang.IllegalStateException: 无法启动新事务 (当前线程已经有事务):GridNearTxLocal [mappings=IgniteTxMappingsImpl [], nearLocallyMapped=false, colocatedLocallyMapped=false,需要CheckBackup=null, hasRemoteLocks=true, trackTimeout=false, lb=null, mvccTracker=null, mvccOp=null, thread=Executor task launch worker for task 290, mappings=IgniteTxMappingsImpl [], super=GridDhtTxLocalAdapter [nearOnOriginatingNode=false,nearNodes=[],dhtNodes=[], 显式锁定=假,超级=IgniteTxLocalAdapter [完成基础=空, 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,conflictExpireTime=-1,conflictVer=null,explicitVer=null, 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]]],prepared=0,locked=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, order=1554721151514, nodeOrder=44],writeVer=null,implicit=false,loc=true,threadId=3770, 开始时间=1554721555785,节点ID=6fb5bb88-fc57-478e-9fb9-c26cc8a311e8, startVer=GridCacheVersion [topVer=166176849, order=1554721151514, nodeOrder=44],endVer=null,隔离=REPEATABLE_READ, 并发=PESSIMISTIC,超时=0,sysInvalidate=false,sys=false, plc=2,commitVer=null,finalizing=NONE,invalidParts=null, state=ACTIVE,timedOut=false,topVer=AffinityTopologyVersion [topVer=44, minorTopVer=0], txCounters=null, 持续时间=156ms, 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,没有发生错误,但无法实现事务锁定。谁能解释我哪里错了?
【问题讨论】:
-
只是好奇为什么你需要异步方法,如果它是一个单一的方法并且你接下来要提交它。
-
有影响吗?但是是的,我尝试使用同步放置。同样的问题。
标签: java mysql multithreading transactions ignite