Skip to content

Commit

Permalink
Capture exceptions and ensure disposal of transaction/repository
Browse files Browse the repository at this point in the history
  • Loading branch information
fubar-coder committed Jan 21, 2022
1 parent f8fbec8 commit 4953d32
Showing 1 changed file with 55 additions and 27 deletions.
82 changes: 55 additions & 27 deletions FubarDev.UnitOfWork/UnitOfWorkFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -189,6 +190,7 @@ internal async ValueTask FinishAsync(
finalizingInfo = _statusManager.Complete(statusItem, status);
}

var capturedExceptions = new List<Exception>();
foreach (var item in finalizingInfo.CompletedStatusItems)
{
IUnitOfWork<TRepository> unitOfWork;
Expand All @@ -205,40 +207,66 @@ internal async ValueTask FinishAsync(
unitOfWork.Id,
finalStatus);

if (statusItem.SaveChangesOnDispose
&& finalStatus is StatusItemResult.Undefined or StatusItemResult.Commit)
try
{
// Flush all changes
await _repositoryManager.SaveChangesAsync(item.Repository, cancellationToken);
}

var transaction = item.NewTransaction;
if (transaction != null)
{
// Committing the transaction should implicitly save the changes,
// while rolling back shouldn't.
switch (finalStatus)
try
{
case StatusItemResult.Commit:
await transaction.CommitAsync(cancellationToken);
break;
case StatusItemResult.Undefined:
case StatusItemResult.Rollback:
await transaction.RollbackAsync(cancellationToken);
break;
default:
throw new NotSupportedException(
$"Status {status} is nt supported for a transactional unit of work");
if (statusItem.SaveChangesOnDispose
&& finalStatus is StatusItemResult.Undefined or StatusItemResult.Commit)
{
// Flush all changes
await _repositoryManager.SaveChangesAsync(item.Repository, cancellationToken);
}

var transaction = item.NewTransaction;
if (transaction != null)
{
// Committing the transaction should implicitly save the changes,
// while rolling back shouldn't.
try
{
switch (finalStatus)
{
case StatusItemResult.Commit:
await transaction.CommitAsync(cancellationToken);
break;
case StatusItemResult.Undefined:
case StatusItemResult.Rollback:
await transaction.RollbackAsync(cancellationToken);
break;
default:
throw new NotSupportedException(
$"Status {status} is nt supported for a transactional unit of work");
}
}
finally
{
await TryDisposeAsync(transaction);
}
}
}
finally
{
if (item.IsNewRepository)
{
await TryDisposeAsync(item.Repository);
}
}

await TryDisposeAsync(transaction);
}

if (item.IsNewRepository)
catch (Exception exception)
{
await TryDisposeAsync(item.Repository);
capturedExceptions.Add(exception);
}
}

if (capturedExceptions.Count == 1)
{
ExceptionDispatchInfo.Capture(capturedExceptions[0]).Throw();
}
else if (capturedExceptions.Count > 1)
{
throw new AggregateException(capturedExceptions);
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down

0 comments on commit 4953d32

Please sign in to comment.