【问题标题】:java.lang.IllegalStateException: Failed to start new transaction (current thread already has a transactionjava.lang.IllegalStateException:启动新事务失败(当前线程已有事务
【发布时间】: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


【解决方案1】:

也许你确实没有关闭一些交易。

我的建议是在try() 子句中打开交易,close()finally{} 中打开它

【讨论】:

  • 错误已解决,但事务方法丢失。再添加一个我提到的在不同 JVM 上运行的多线程。
  • 我不明白你在说什么。请注意,您可以在一个线程中suspend() 点燃Transaction,在另一个线程中点燃resume()。如果您在单个 tx 中依赖多线程,请尝试一下。
猜你喜欢
  • 1970-01-01
  • 2014-01-13
  • 2021-12-24
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 2015-10-25
  • 1970-01-01
相关资源
最近更新 更多