Uploaded image for project: 'Infinispan'
  1. Infinispan
  2. ISPN-9314

AtomicKeySetImpl deserialization should not modify running transaction

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Major
    • 9.3.0.Final
    • 9.3.0.CR1
    • Core
    • None

    Description

      AtomicKeySetImpl.Externalizer.readObject() invokes a GetKeysInGroupCommand with a new context, but if a transaction is already running on the same thread it will reuse the transaction. Since tx contexts are just a wrapper over the CacheTransaction, looking up entries for the GetKeysInGroupCommand modifies the parent invocation context as well.

      Every time an AtomicKeySetImpl is read in a transaction and then passivated before commit, the externalizer thus adds the members of the group in the parent transaction's context:

      testng-test: Committing {AtomicKeySetImpl.Key{group=key1, key=second}=VersionedRepeatableReadEntry(58cf8f94){key=AtomicKeySetImpl.Key{group=key1, key=second}, value=second component of object with key=key1, isCreated=true, isChanged=true, isRemoved=false, isExpired=false, skipLookup=true, metadata=EmbeddedExpirableMetadata{lifespan=-1, maxIdle=-1, version=NumericVersion{version=0}}}, key1=VersionedRepeatableReadEntry(66c38e51)
      
      {key=key1, value=AtomicKeySetImpl{keys=[AtomicKeySetImpl.Key{group=key1, key=first}, first], added=[second], removed=null}, isCreated=false, isChanged=true, isRemoved=false, isExpired=false, skipLookup=true, metadata=MetaParamsInternalMetadata{params=MetaParams{length=1, metas=[MetaEntryVersion=NumericVersion{version=2}]}}}}
      
      Breakpoint reached
      	  at org.infinispan.transaction.impl.LocalTransaction.putLookedUpEntry(LocalTransaction.java:107)
      	  at org.infinispan.context.impl.AbstractTxInvocationContext.putLookedUpEntry(AbstractTxInvocationContext.java:105)
      	  at org.infinispan.container.impl.EntryFactoryImpl.wrapExternalEntry(EntryFactoryImpl.java:173)
      	  at org.infinispan.interceptors.impl.CacheLoaderInterceptor.lambda$visitGetKeysInGroupCommand$2(CacheLoaderInterceptor.java:208)
      	  at org.infinispan.interceptors.impl.CacheLoaderInterceptor$$Lambda$304.1315908533.accept(Unknown Source:-1)
      	  at io.reactivex.Flowable.blockingForEach(Flowable.java:5325)
      	  at org.infinispan.interceptors.impl.CacheLoaderInterceptor.visitGetKeysInGroupCommand(CacheLoaderInterceptor.java:208)
      	  at org.infinispan.commands.remote.GetKeysInGroupCommand.acceptVisitor(GetKeysInGroupCommand.java:91)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextThenAccept(BaseAsyncInterceptor.java:98)
      	  at org.infinispan.interceptors.impl.EntryWrappingInterceptor.visitGetKeysInGroupCommand(EntryWrappingInterceptor.java:427)
      	  at org.infinispan.commands.remote.GetKeysInGroupCommand.acceptVisitor(GetKeysInGroupCommand.java:91)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndFinally(BaseAsyncInterceptor.java:150)
      	  at org.infinispan.interceptors.impl.GroupingInterceptor.visitGetKeysInGroupCommand(GroupingInterceptor.java:50)
      	  at org.infinispan.commands.remote.GetKeysInGroupCommand.acceptVisitor(GetKeysInGroupCommand.java:91)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.visitGetKeysInGroupCommand(DDAsyncInterceptor.java:177)
      	  at org.infinispan.commands.remote.GetKeysInGroupCommand.acceptVisitor(GetKeysInGroupCommand.java:91)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.visitGetKeysInGroupCommand(DDAsyncInterceptor.java:177)
      	  at org.infinispan.commands.remote.GetKeysInGroupCommand.acceptVisitor(GetKeysInGroupCommand.java:91)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.visitGetKeysInGroupCommand(DDAsyncInterceptor.java:177)
      	  at org.infinispan.commands.remote.GetKeysInGroupCommand.acceptVisitor(GetKeysInGroupCommand.java:91)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.visitGetKeysInGroupCommand(DDAsyncInterceptor.java:177)
      	  at org.infinispan.commands.remote.GetKeysInGroupCommand.acceptVisitor(GetKeysInGroupCommand.java:91)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndExceptionally(BaseAsyncInterceptor.java:123)
      	  at org.infinispan.interceptors.impl.InvocationContextInterceptor.visitCommand(InvocationContextInterceptor.java:90)
      	  at org.infinispan.interceptors.impl.AsyncInterceptorChainImpl.invoke(AsyncInterceptorChainImpl.java:248)
      	  at org.infinispan.atomic.impl.AtomicKeySetImpl$Externalizer.readObject(AtomicKeySetImpl.java:498)
      	  at org.infinispan.atomic.impl.AtomicKeySetImpl$Externalizer.readObject(AtomicKeySetImpl.java:466)
      	  at org.infinispan.marshall.core.GlobalMarshaller.readWithExternalizer(GlobalMarshaller.java:708)
      	  at org.infinispan.marshall.core.GlobalMarshaller.readNonNullableObject(GlobalMarshaller.java:691)
      	  at org.infinispan.marshall.core.GlobalMarshaller.readNullableObject(GlobalMarshaller.java:361)
      	  at org.infinispan.marshall.core.BytesObjectInput.readObject(BytesObjectInput.java:40)
      	  at org.infinispan.util.KeyValuePair$Externalizer.readObject(KeyValuePair.java:49)
      	  at org.infinispan.util.KeyValuePair$Externalizer.readObject(KeyValuePair.java:37)
      	  at org.infinispan.marshall.core.GlobalMarshaller.readWithExternalizer(GlobalMarshaller.java:708)
      	  at org.infinispan.marshall.core.GlobalMarshaller.readNonNullableObject(GlobalMarshaller.java:691)
      	  at org.infinispan.marshall.core.GlobalMarshaller.readNullableObject(GlobalMarshaller.java:361)
      	  at org.infinispan.marshall.core.GlobalMarshaller.objectFromObjectInput(GlobalMarshaller.java:194)
      	  at org.infinispan.marshall.core.GlobalMarshaller.objectFromByteBuffer(GlobalMarshaller.java:190)
      	  at org.infinispan.persistence.dummy.DummyInMemoryStore.deserialize(DummyInMemoryStore.java:363)
      	  at org.infinispan.persistence.dummy.DummyInMemoryStore.load(DummyInMemoryStore.java:160)
      	  at org.infinispan.persistence.manager.PersistenceManagerImpl.loadFromAllStores(PersistenceManagerImpl.java:551)
      	  at org.infinispan.persistence.PersistenceUtil.loadAndCheckExpiration(PersistenceUtil.java:219)
      	  at org.infinispan.persistence.PersistenceUtil.lambda$loadAndComputeInDataContainer$2(PersistenceUtil.java:196)
      	  at org.infinispan.persistence.PersistenceUtil$$Lambda$295.869610006.compute(Unknown Source:-1)
      	  at org.infinispan.container.impl.AbstractInternalDataContainer.lambda$compute$3(AbstractInternalDataContainer.java:231)
      	  at org.infinispan.container.impl.AbstractInternalDataContainer$$Lambda$274.1969969319.apply(Unknown Source:-1)
      	  at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$remap$16(BoundedLocalCache.java:2199)
      	  at com.github.benmanes.caffeine.cache.BoundedLocalCache$$Lambda$275.2081595126.apply(Unknown Source:-1)
      	  at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1853)
      	  at com.github.benmanes.caffeine.cache.BoundedLocalCache.remap(BoundedLocalCache.java:2194)
      	  at com.github.benmanes.caffeine.cache.BoundedLocalCache.compute(BoundedLocalCache.java:2146)
      	  at com.github.benmanes.caffeine.cache.LocalCache.compute(LocalCache.java:100)
      	  at org.infinispan.container.impl.AbstractInternalDataContainer.compute(AbstractInternalDataContainer.java:230)
      	  at org.infinispan.persistence.PersistenceUtil.loadAndComputeInDataContainer(PersistenceUtil.java:206)
      	  at org.infinispan.statetransfer.CommitManager.commitEntry(CommitManager.java:129)
      	  at org.infinispan.statetransfer.CommitManager.commit(CommitManager.java:97)
      	  at org.infinispan.interceptors.locking.ClusteringDependentLogic$LocalLogic.commitSingleEntry(ClusteringDependentLogic.java:352)
      	  at org.infinispan.interceptors.locking.ClusteringDependentLogic$AbstractClusteringDependentLogic.commitEntry(ClusteringDependentLogic.java:189)
      	  at org.infinispan.interceptors.impl.VersionedEntryWrappingInterceptor.commitContextEntry(VersionedEntryWrappingInterceptor.java:116)
      	  at org.infinispan.interceptors.impl.EntryWrappingInterceptor.commitEntryIfNeeded(EntryWrappingInterceptor.java:813)
      	  at org.infinispan.interceptors.impl.EntryWrappingInterceptor.lambda$commitContextEntries$7(EntryWrappingInterceptor.java:570)
      	  at org.infinispan.interceptors.impl.EntryWrappingInterceptor$$Lambda$293.268086000.accept(Unknown Source:-1)
      	  at java.util.HashMap.forEach(HashMap.java:1289)
      	  at org.infinispan.context.EntryLookup.forEachEntry(EntryLookup.java:38)
      	  at org.infinispan.interceptors.impl.EntryWrappingInterceptor.commitContextEntries(EntryWrappingInterceptor.java:569)
      	  at org.infinispan.interceptors.impl.VersionedEntryWrappingInterceptor.doCommit(VersionedEntryWrappingInterceptor.java:95)
      	  at org.infinispan.interceptors.impl.VersionedEntryWrappingInterceptor.lambda$visitCommitCommand$1(VersionedEntryWrappingInterceptor.java:87)
      	  at org.infinispan.interceptors.impl.VersionedEntryWrappingInterceptor$$Lambda$288.836170750.accept(Unknown Source:-1)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndFinally(BaseAsyncInterceptor.java:163)
      	  at org.infinispan.interceptors.impl.VersionedEntryWrappingInterceptor.visitCommitCommand(VersionedEntryWrappingInterceptor.java:86)
      	  at org.infinispan.commands.tx.CommitCommand.acceptVisitor(CommitCommand.java:38)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.visitCommitCommand(DDAsyncInterceptor.java:142)
      	  at org.infinispan.commands.tx.CommitCommand.acceptVisitor(CommitCommand.java:38)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextThenAccept(BaseAsyncInterceptor.java:98)
      	  at org.infinispan.interceptors.impl.NotificationInterceptor.visitCommitCommand(NotificationInterceptor.java:46)
      	  at org.infinispan.commands.tx.CommitCommand.acceptVisitor(CommitCommand.java:38)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndFinally(BaseAsyncInterceptor.java:150)
      	  at org.infinispan.interceptors.locking.AbstractTxLockingInterceptor.visitCommitCommand(AbstractTxLockingInterceptor.java:51)
      	  at org.infinispan.commands.tx.CommitCommand.acceptVisitor(CommitCommand.java:38)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextThenAccept(BaseAsyncInterceptor.java:98)
      	  at org.infinispan.interceptors.impl.TxInterceptor.finishCommit(TxInterceptor.java:189)
      	  at org.infinispan.interceptors.impl.TxInterceptor.visitCommitCommand(TxInterceptor.java:183)
      	  at org.infinispan.commands.tx.CommitCommand.acceptVisitor(CommitCommand.java:38)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54)
      	  at org.infinispan.interceptors.DDAsyncInterceptor.visitCommitCommand(DDAsyncInterceptor.java:142)
      	  at org.infinispan.commands.tx.CommitCommand.acceptVisitor(CommitCommand.java:38)
      	  at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndExceptionally(BaseAsyncInterceptor.java:123)
      	  at org.infinispan.interceptors.impl.InvocationContextInterceptor.visitCommand(InvocationContextInterceptor.java:90)
      	  at org.infinispan.interceptors.impl.AsyncInterceptorChainImpl.invoke(AsyncInterceptorChainImpl.java:248)
      	  at org.infinispan.interceptors.InterceptorChain.invoke(InterceptorChain.java:137)
      	  at org.infinispan.transaction.impl.TransactionCoordinator.commitInternal(TransactionCoordinator.java:219)
      	  at org.infinispan.transaction.impl.TransactionCoordinator.commit(TransactionCoordinator.java:161)
      	  at org.infinispan.transaction.xa.XaTransactionTable.commit(XaTransactionTable.java:125)
      	  at org.infinispan.transaction.xa.TransactionXaAdapter.commit(TransactionXaAdapter.java:68)
      	  at com.arjuna.ats.internal.jta.resources.arjunacore.XAResourceRecord.topLevelOnePhaseCommit(XAResourceRecord.java:698)
      	  at com.arjuna.ats.arjuna.coordinator.BasicAction.onePhaseCommit(BasicAction.java:2364)
      	  at com.arjuna.ats.arjuna.coordinator.BasicAction.End(BasicAction.java:1518)
      	  at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:96)
      	  at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162)
      	  at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1200)
      	  at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:126)
      	  at org.infinispan.atomic.impl.TransactionHelper.run(TransactionHelper.java:75)
      	  at org.infinispan.atomic.impl.FineGrainedAtomicMapProxyImpl.put(FineGrainedAtomicMapProxyImpl.java:186)
      	  at org.infinispan.atomic.LocalDeltaAwareEvictionTest$5.createObject(LocalDeltaAwareEvictionTest.java:279)
      	  at org.infinispan.atomic.LocalDeltaAwareEvictionTest$5.createObject(LocalDeltaAwareEvictionTest.java:273)
      	  at org.infinispan.atomic.LocalDeltaAwareEvictionTest$1.call(LocalDeltaAwareEvictionTest.java:95)
      	  at org.infinispan.atomic.LocalDeltaAwareEvictionTest.withTx(LocalDeltaAwareEvictionTest.java:78)
      	  at org.infinispan.atomic.LocalDeltaAwareEvictionTest.test(LocalDeltaAwareEvictionTest.java:92)
      	  at org.infinispan.atomic.LocalDeltaAwareEvictionTest.testFineGrainedAtomicMap(LocalDeltaAwareEvictionTest.java:269)
      
      testng-test: Adding entry AtomicKeySetImpl.Key{group=key1, key=first} : VersionedRepeatableReadEntry(fabb651){key=AtomicKeySetImpl.Key{group=key1, key=first}, value=first component of object with key=key1, isCreated=false, isChanged=false, isRemoved=false, isExpired=false, skipLookup=false, metadata=EmbeddedExpirableMetadata{lifespan=-1, maxIdle=-1, version=NumericVersion{version=2}}}
      

      Interesting enough, the Iterator-based iteration in EntryWrappingInterceptor.commitContextEntries doesn't throw a ConcurrentModificationException after this modification (at least in LocalDeltaAwareEvictionTest). It only started failing after I replaced the iterator with HashMap.forEach().

      Attachments

        Activity

          People

            dberinde@redhat.com Dan Berindei (Inactive)
            dberinde@redhat.com Dan Berindei (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: