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); } } } }
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()); } }
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()); } }
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; } } } }
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)); }
public static Func <Task <DbConnection> > ToAsyncConnectionFactory(this IDbFactory factory) { return(() => factory.CreateAsync(CancellationToken.None, (string)null)); }