Dead Lock: delete with optimize

Description

With this option, the index is optimized for each transaction.
x.SetProperty("hibernate.search.default.optimizer.transaction_limit.max", "0");

Delete workflow:
• Delete-Work is performed.
• Delete-Work opens an index reader and lock the provider.
• Delete-Work is finished.

• CleanUp is performed.
• All index readers are closed.

• CleanUp starts the optimizer.
• Optimizer opens an index writer and lock the provider.

• Back on the CleanUp method.
• All index writer are closed.

• For each locked provider Monitor.Exit (provider) is called.
• Finish.

Monitor.Enter(provider) was executed twice but Monitor.Exit(provider) only once.
Delete the next time we have a dead lock.

Line 204 - 224 LockProvider in Backend\Workspace
Now:
private void LockProvider(IDirectoryProvider provider)
{
// Make sure to use a semaphore
object syncLock = searchFactoryImplementor.GetLockableDirectoryProviders()[provider];
Monitor.Enter(syncLock);
try
{
if (!lockedProviders.Contains(provider))
{
lockedProviders.Add(provider);
dpStatistics.Add(provider, new DPStatistics());
}

}
catch (Exception)
{
// NB This is correct here, we release the lock only if we have an error
Monitor.Exit(syncLock);
throw;
}
}

Solving:
private void LockProvider(IDirectoryProvider provider)
{
//Provider only lock once
if (!lockedProviders.Contains(provider))
{
// Make sure to use a semaphore
object syncLock = searchFactoryImplementor.GetLockableDirectoryProviders()[provider];
Monitor.Enter(syncLock);
try
{
lockedProviders.Add(provider);
dpStatistics.Add(provider, new DPStatistics());
}
catch (Exception)
{
// NB This is correct here, we release the lock only if we have an error
Monitor.Exit(syncLock);
throw;
}
}
}

Environment

None

Assignee

PaulP

Reporter

RAB

Labels

None

Components

Affects versions

Priority

Critical
Configure