UnitOfWorkManager is not Thread Safe
duereg opened this issue · comments
UnitOfWorkManager is not thread safe. Multiple TransactionManagers can be created in a multi-threaded environment.
To fix this issue, I've changed the following method to add a double-lock on the TransactionManager creation.
private static readonly object _lock = new Object();
static readonly Func DefaultTransactionManager = () =>
{
_logger.Debug(x => x("Using default UnitOfWorkManager provider to resolve current transaction manager."));
var state = ServiceLocator.Current.GetInstance();
var transactionManager = state.Local.Get(LocalTransactionManagerKey);
if (transactionManager == null)
{
lock (_lock)
{
if (transactionManager == null)
{
_logger.Debug(x => x("No valid ITransactionManager found in Local state. Creating a new TransactionManager."));
transactionManager = new TransactionManager();
state.Local.Put(LocalTransactionManagerKey, transactionManager);
}
}
}
return transactionManager;
};
The second check for transactionManager will always return true since you're just testing the local variable. You should refresh the transactionManager from the local state again:
lock (_lock)
{
if ((transactionManager = state.Local.Get<ITransactionManager>(LocalTransactionManagerKey))== null)
{ ..}
}