public void Save <T>(T @object) where T : class, IPersistable { using (TransactionScope tx = new TransactionScope(this)) { tx.Context.Set(new TimestampContext(DateTime.Now), true); tx.Context.Set(new CommandContext(ID.NewID()), true); // HACK tx.GetRequiredService <IRepository <T> >().Save(@object).Wait(); tx.CommitAsync().Wait(); } }
public TransactionScopeHandler(IServiceProvider services) { Register(async(ExecuteCommand e) => { using (var scope = new TransactionScope(services, e.Context)) { scope.Context.Set(new CommandContext(e.Command.ID), true); scope.Context.Set(new TimestampContext(DateTime.Now), true); e.Context = scope.Context; await Next(e).Get(); try { await scope.CommitAsync(); } catch (Exception ex) { // HACK!!!!!!!!!!!!!!!!!!!!!!!!! } } }); }
public CommandPersister( IServiceProvider services, ICommandMetadataProvider metadataProvider, ContractTypeSerializer serializer ) { Register(async(QueueCommand q) => { var queueSource = new TaskCompletionSource <QueueCommandResultType>(); var ctx = new CommandPersisterContext(queueSource.Task); var resultType = QueueCommandResultType.Unknown; try { q.Context.Set(ctx, true); QueueCommandResult result = await Next(q).Get(); resultType = result.Type; if (result.Type == QueueCommandResultType.SuccessfullyQueued) { using (var scope = new TransactionScope(services, q.Context)) { scope.Context.Set(new TimestampContext(DateTime.Now), true); scope.Context.Set(new CommandContext(q.Command.ID), true); QueueHelper h = new QueueHelper( serializer, repository: scope.GetRepository <ServerCommand>(), command: q.Command, metadata: metadataProvider.Provide(q.Context) ); if (await h.LoadExisting()) { if (!h.ExistingMatchesCurrent()) { resultType = QueueCommandResultType.Rejected; return(QueueCommandResult.Rejected()); } if (h.ExistingCompletedSuccessfully()) { resultType = QueueCommandResultType.AlreadyExecuted; return(QueueCommandResult.AlreadyExecuted()); } } ctx.Command = await h.CompleteQueue(); await scope.CommitAsync(); } } return(result); } finally { queueSource.SetResult(resultType); } }); Register(async(ExecuteCommand e) => { var persisterCtx = e.Context.Get <CommandPersisterContext>(); if (await persisterCtx.QueueTask != QueueCommandResultType.SuccessfullyQueued) { return; } ServerCommand sc = persisterCtx.Command.NotNull(); IServiceProvider sp = e.Context.Get <IServiceProvider>(); sc.BeginExecution(DateTime.Now); await sp .GetRepository <ServerCommand>() .Save(sc); await sp.GetRequiredService <ITransaction>().CommitAsync(); try { await Next(e).Get(); // We have to use a new transaction here, because the oiginal one may time // out if the execution of the command takes very long. using (var scope = new TransactionScope(sp, e.Context)) { sc.EndExecution(DateTime.Now); await scope .GetRepository <ServerCommand>() .Save(sc); await scope.CommitAsync(); } } catch (Exception ex) when(!ex.IsCritical()) { using (var scope = new TransactionScope(services, e.Context)) { scope.Context.Set(new TimestampContext(DateTime.Now), true); scope.Context.Set(new CommandContext(e.Command.ID), true); sc.EndExecution(DateTime.Now, ex); await scope .GetRepository <ServerCommand>() .Save(sc); await scope.CommitAsync(); } throw; } }); }