public async Task AddAsync(UniqueStoreItem item, CancellationToken cancel)
        {
            using (var db = await _db.CreateAsync(cancel).ConfigureFalse())
            {
                using (var t = db.BeginTransaction())
                {
                    if (await db.IsDuplicateOperationAsync(item.ToIdempotencyId(), cancel))
                    {
                        return;
                    }

                    try
                    {
                        item.Uniques
                        .Select(d => new UniqueStoreRow(item.EntityId, d.Scope, d.Aspect, d.Value, item.Bucket))
                        .ForEach(row => db.Insert(row));

                        t.Commit();
                    }
                    catch (DbException ex) when(db.IsUniqueViolation(ex))
                    {
                        throw new UniqueStoreDuplicateException(ex.Message);
                    }
                }
            }
        }
Example #2
0
 public static async Task <T> DoAsync <T>(this IDbFactory fac, Func <DbConnection, Task <T> > act, CancellationToken?cancel = null)
 {
     using (var db = await fac.CreateAsync(cancel ?? CancellationToken.None).ConfigureFalse())
     {
         return(await act(db).ConfigureFalse());
     }
 }
Example #3
0
        public async Task <TResult> Get(TInput i, CancellationToken?cancel)
        {
            var c = cancel ?? CancellationToken.None;

            using (var db = await _getDb.CreateAsync(c).ConfigureFalse())
            {
                return(await Execute(i, db, c).ConfigureFalse());
            }
        }
Example #4
0
        public async Task <AppendResult> Append(UnversionedCommit commit)
        {
            using (var db = await _db.CreateAsync(CancellationToken.None))
            {
                using (var t = db.BeginTransaction())
                {
                    var max = await db.QueryValueAsync <int?>(q =>
                                                              q.From <Commit>().Where(d => d.EntityId == commit.EntityId && d.TenantId == commit.TenantId)
                                                              .Select(d => d.Max(d.Version)).MapTo <int?>(), CancellationToken.None).ConfigureFalse() ?? 0;

                    var com = new Commit(max + 1, commit);
                    try
                    {
                        await db.InsertAsync(com, CancellationToken.None).ConfigureFalse();

                        t.Commit();
                        return(AppendResult.Ok);
                    }
                    catch (DbException ex)
                    {
                        if (ex.Message.Contains(DuplicateCommmitMessage))
                        {
                            var existing = await db
                                           .QueryRowAsync <Commit>(
                                q => q.From <Commit>()
                                .Where(d => d.CommitId == commit.CommitId && d.EntityId == commit.EntityId && d.TenantId == commit.TenantId)
                                .Limit(1)
                                .SelectAll(useAsterisk: true), CancellationToken.None).ConfigureFalse();

                            return(new AppendResult(existing));
                        }

                        if (ex.Message.Contains(DuplicateVersion))
                        {
                            throw new ConcurrencyException();
                        }
                        throw;
                    }
                }
            }
        }
Example #5
0
 public static Task RetryOnTransientErrorAsync(this IDbFactory factory, CancellationToken token, Func <IWithSqlAsync, Task> action)
 {
     return(ModelTools.RetryOnException <DbException>(async() =>
     {
         using (var db = await factory.CreateAsync(token).ConfigureAwait(false))
         {
             var op = new ResilientWithSql(db, token);
             await action(op).ConfigureAwait(false);
         }
     }, x =>
     {
         if (factory.Provider.IsDbBusy(x))
         {
             return OnExceptionAction.IgnoreAndContinue;
         }
         return OnExceptionAction.Throw;
     }, SqlFuManager.Config.TransientErrors.Tries, SqlFuManager.Config.TransientErrors.Wait));
 }
Example #6
0
 public static Func <Task <DbConnection> > ToAsyncConnectionFactory(this IDbFactory factory)
 {
     return(() => factory.CreateAsync(CancellationToken.None, (string)null));
 }