public BatchResult[] Batch(IEnumerable<ICommandData> commands)
{
var results = new List<BatchResult>();
var commandDatas = commands.ToArray();
int retries = 128;
var shouldLock = commandDatas.Any(x=>x is PutCommandData || x is PatchCommandData);
var shouldRetryIfGotConcurrencyError = commandDatas.All(x => x is PatchCommandData);
bool shouldRetry = false;
if(shouldLock)
Monitor.Enter(putSerialLock);
try
{
log.Debug("Executing batched commands in a single transaction");
do
{
try
{
TransactionalStorage.Batch(actions =>
{
foreach (var command in commandDatas)
{
command.Execute(this);
results.Add(new BatchResult
{
Method = command.Method,
Key = command.Key,
Etag = command.Etag,
Metadata = command.Metadata
});
}
workContext.ShouldNotifyAboutWork();
});
}
catch (ConcurrencyException)
{
if (shouldRetryIfGotConcurrencyError && retries-- > 128)
{
shouldRetry = true;
results.Clear();
continue;
}
throw;
}
} while (shouldRetry);
log.Debug("Successfully executed {0} commands", results.Count);
}
finally
{
if(shouldLock)
Monitor.Exit(putSerialLock);
}
return results.ToArray();
}