[infinispan-dev] fixing eviction with transactions (critical for Hibernate Search)
Sanne Grinovero
sanne.grinovero at gmail.com
Tue Jun 7 08:13:05 EDT 2011
Hello all,
in this scenario we have the Infinispan Lucene Directory using
batching (DummyTransaction), eviction and passivation to keep the
amount of memory being used for the index under control; I'm using
LIRS but experienced the same issue with all other strategies.
As you can see from the following stacktrace, the batching ends by
sending a commit request, so the status of the transaction is 8
(STATUS_COMMITTING) in this context.
The new data is stored in the DataContainer, then the
BoundedConcurrentHashMap notifies the EvictionManagerImpl as it has to
evict some values, and this one attempts to acquire a lock on the
to-be-evicted keys (which are obviously not the same I'm trying to
store).
Acquiring this lock is an invalid operation as the transaction is in
commit state, and so this operation fails with an exception.
Thread [Hibernate Search: Directory writer-1] (Suspended (breakpoint
at line 92 in LockManagerImpl))
LockManagerImpl.lockAndRecord(Object, InvocationContext) line: 92
EvictionManagerImpl.acquireLock(InvocationContext, Object) line: 210
EvictionManagerImpl.onEntryEviction(Object, InternalCacheEntry) line: 170
EvictionManagerImpl.onEntryEviction(Map<Object,InternalCacheEntry>) line: 162
DefaultDataContainer$DefaultEvictionListener.onEntryEviction(Map<Object,InternalCacheEntry>)
line: 201
BoundedConcurrentHashMap$Segment<K,V>.notifyEvictionListener(Set<HashEntry<K,V>>)
line: 1176
BoundedConcurrentHashMap$Segment<K,V>.put(K, int, V, boolean) line: 1011
BoundedConcurrentHashMap<K,V>.put(K, V) line: 1556
DefaultDataContainer.put(Object, Object, long, long) line: 148
ReadCommittedEntry.commit(DataContainer) line: 177
LockingInterceptor.commitEntry(CacheEntry, boolean) line: 389
LockingInterceptor.cleanupLocks(InvocationContext, boolean) line: 367
LockingInterceptor.visitCommitCommand(TxInvocationContext,
CommitCommand) line: 98
CommitCommand.acceptVisitor(InvocationContext, Visitor) line: 60
CacheStoreInterceptor(CommandInterceptor).invokeNextInterceptor(InvocationContext,
VisitableCommand) line: 119
CacheStoreInterceptor.visitCommitCommand(TxInvocationContext,
CommitCommand) line: 148
CommitCommand.acceptVisitor(InvocationContext, Visitor) line: 60
CacheLoaderInterceptor(CommandInterceptor).invokeNextInterceptor(InvocationContext,
VisitableCommand) line: 119
CacheLoaderInterceptor(CommandInterceptor).handleDefault(InvocationContext,
VisitableCommand) line: 133
CacheLoaderInterceptor(AbstractVisitor).visitCommitCommand(TxInvocationContext,
CommitCommand) line: 116
CommitCommand.acceptVisitor(InvocationContext, Visitor) line: 60
NotificationInterceptor(CommandInterceptor).invokeNextInterceptor(InvocationContext,
VisitableCommand) line: 119
NotificationInterceptor.visitCommitCommand(TxInvocationContext,
CommitCommand) line: 56
CommitCommand.acceptVisitor(InvocationContext, Visitor) line: 60
TxInterceptor(CommandInterceptor).invokeNextInterceptor(InvocationContext,
VisitableCommand) line: 119
TxInterceptor.visitCommitCommand(TxInvocationContext, CommitCommand) line: 142
CommitCommand.acceptVisitor(InvocationContext, Visitor) line: 60
CacheMgmtInterceptor(CommandInterceptor).invokeNextInterceptor(InvocationContext,
VisitableCommand) line: 119
CacheMgmtInterceptor(CommandInterceptor).handleDefault(InvocationContext,
VisitableCommand) line: 133
CacheMgmtInterceptor(AbstractVisitor).visitCommitCommand(TxInvocationContext,
CommitCommand) line: 116
CommitCommand.acceptVisitor(InvocationContext, Visitor) line: 60
InvocationContextInterceptor(CommandInterceptor).invokeNextInterceptor(InvocationContext,
VisitableCommand) line: 119
InvocationContextInterceptor.handleAll(InvocationContext,
VisitableCommand) line: 96
InvocationContextInterceptor.handleDefault(InvocationContext,
VisitableCommand) line: 63
InvocationContextInterceptor(AbstractVisitor).visitCommitCommand(TxInvocationContext,
CommitCommand) line: 116
CommitCommand.acceptVisitor(InvocationContext, Visitor) line: 60
BatchingInterceptor(CommandInterceptor).invokeNextInterceptor(InvocationContext,
VisitableCommand) line: 119
BatchingInterceptor.handleDefault(InvocationContext,
VisitableCommand) line: 77
BatchingInterceptor(AbstractVisitor).visitCommitCommand(TxInvocationContext,
CommitCommand) line: 116
CommitCommand.acceptVisitor(InvocationContext, Visitor) line: 60
InterceptorChain.invoke(InvocationContext, VisitableCommand) line: 274
TransactionCoordinator.commit(LocalTransaction, boolean) line: 136
TransactionXaAdapter.commit(Xid, boolean) line: 124
DummyTransaction.runCommitTx() line: 312
DummyTransaction.commit() line: 99
BatchModeTransactionManager(DummyBaseTransactionManager).commit() line: 97
BatchContainer.resolveTransaction(BatchContainer$BatchDetails,
boolean) line: 131
BatchContainer.endBatch(boolean, boolean) line: 108
BatchContainer.endBatch(boolean) line: 93
CacheDelegate<K,V>.endBatch(boolean) line: 436
InfinispanIndexOutput.close() line: 208
IOUtils.closeSafely(Closeable...) line: 80
FieldsWriter.close() line: 111
StoredFieldsWriter.flush(SegmentWriteState) line: 52
DocFieldProcessor.flush(Collection<DocConsumerPerThread>,
SegmentWriteState) line: 58
I would like to remove the lock operation from the eviction listener,
but I'm not understanding why this locking is needed there and would
appreciate some explanations or help with this.
Shouldn't an evict operation be a "best effort" operation in all
cases, or is the idea here that we want the evictable data to be
consistently evicted on multiple nodes, or maybe even rollback an
evict operation?
Cheers,
Sanne
More information about the infinispan-dev
mailing list