// 异步执行工作单元 private void PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options) { var uow = _unitOfWorkManager.Begin(options); invocation.Proceed(); if (invocation.Method.ReturnType == typeof(Task)) { invocation.ReturnValue = AsyncHelper.AwaitTaskWithPostActionAndFinally( (Task)invocation.ReturnValue, async () => await uow.CompleteAsync(), exception => uow.Dispose() ); } else { //Task<TResult> invocation.ReturnValue = AsyncHelper.CallAwaitTaskWithPostActionAndFinallyAndGetResult( invocation.Method.ReturnType.GenericTypeArguments[0], invocation.ReturnValue, async () => await uow.CompleteAsync(), (exception) => uow.Dispose() ); } }
// 同步执行工作单元 private void PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options) { using (var uow = _unitOfWorkManager.Begin(options)) { invocation.Proceed(); uow.Complete(); } }
// 执行工作单元 private void PerformUow(IInvocation invocation, UnitOfWorkOptions options) { if (AsyncHelper.IsAsyncMethod(invocation.Method)) { PerformAsyncUow(invocation, options); } else { PerformSyncUow(invocation, options); } }
public bool TryBeginReserved(string reservationName, UnitOfWorkOptions options) { Check.NotNull(reservationName, nameof(reservationName)); var uow = _ambientUnitOfWork.UnitOfWork; //Find reserved unit of work starting from current and going to outers while (uow != null && !uow.IsReservedFor(reservationName)) { uow = uow.Outer; } if (uow == null) { return(false); } uow.Initialize(options); return(true); }
public void Multiple_connections_errors_are_ignored_when_the_appropriate_option_is_specified() { var sqliteDatabaseConnectionString = new SQLiteDatabaseConnectionString("Data Source = whatever.db"); var sqliteDatabaseConnectionFactory = new SQLiteDatabaseConnectionFactory(sqliteDatabaseConnectionString); var options = new UnitOfWorkOptions { ThrowOnMultipleTransactionsAttempts = true, ThrowOnMultipleConnectionsAttempts = false }; using var unitOfWork = new SynchronousUnitOfWork(sqliteDatabaseConnectionFactory, options); unitOfWork.OpenConnection(); void OpenConnectionAgain() { unitOfWork.OpenConnection(); } Assert.DoesNotThrow(OpenConnectionAgain); }
/// <inheritdoc /> protected override void BeginUow(UnitOfWorkOptions uowOptions) { _uowOptions = uowOptions; if (_uowOptions.IsTransactional == true && _transactionScope == null) { var transactionOptions = new TransactionOptions { IsolationLevel = _uowOptions.IsolationLevel, }; if (_uowOptions.Timeout.HasValue) { transactionOptions.Timeout = _uowOptions.Timeout.Value; } _transactionScope = new TransactionScope( _uowOptions.Scope, transactionOptions, _uowOptions.AsyncFlowOption ); } }
public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) { if (context.HandlerMethod == null) { await next(); return; } var unitOfWorkAttr = _unitOfWorkDefaultOptions .GetUnitOfWorkAttributeOrNull(context.HandlerMethod.MethodInfo) ?? _aspnetCoreConfiguration.DefaultUnitOfWorkAttribute; if (unitOfWorkAttr.IsDisabled) { await next(); return; } var uowOpts = new UnitOfWorkOptions { IsTransactional = unitOfWorkAttr.IsTransactional, IsolationLevel = unitOfWorkAttr.IsolationLevel, Timeout = unitOfWorkAttr.Timeout, Scope = unitOfWorkAttr.Scope }; using (var uow = _unitOfWorkManager.Begin(uowOpts)) { var result = await next(); if (result.Exception == null || result.ExceptionHandled) { await uow.CompleteAsync(); } } }
public async Task UnitOfWorkEvent_WillTrigger_Async() { var provider = GetServiceProvider(AddScopeTransactionProvider); var uowManager = provider.GetService <IUnitOfWorkManager>(); var currentDbExecutor = new ScopeDbExecutor(new FakeDbContext()); string saveChangedInfo = ""; string rollbackInfo = ""; var options = new UnitOfWorkOptions(); options.Events.OnCompleted += s => { saveChangedInfo = "over"; return(Task.CompletedTask); }; options.Events.OnRollbacked += s => { rollbackInfo = "over"; return(Task.CompletedTask); }; using (var uow = uowManager.Create(options)) { await uow.TryAddDbExecutorAsync(currentDbExecutor); await uow.SaveChangesAsync(); await uow.RollbackAsync(); } Assert.Equal("over", saveChangedInfo); Assert.Equal("over", rollbackInfo); //uow结束,则uow2包含的操作也将释放 Assert.True(currentDbExecutor.IsDispose); }
public void InstantiateAndCommitAndDispose_WithDefaults_StartsAndCommitsAndDisposesTransaction() { // arrange var loggerFactory = new Mock <IBoltOnLoggerFactory>(); var logger = new Mock <IBoltOnLogger <UnitOfWork> >(); var unitOfWorkOptions = new UnitOfWorkOptions(); loggerFactory.Setup(u => u.Create <UnitOfWork>()).Returns(logger.Object); // act using (var sut = new UnitOfWork(loggerFactory.Object, unitOfWorkOptions)) { sut.Commit(); } // assert logger.Verify(l => l.Debug("Starting UoW...")); logger.Verify(l => l.Debug("Started UoW")); logger.Verify(l => l.Debug("Committing UoW...")); logger.Verify(l => l.Debug("Committed UoW")); logger.Verify(l => l.Debug("Disposing UoW...")); logger.Verify(l => l.Debug("Disposed UoW")); }
public void Begin(UnitOfWorkOptions options) { if (options == null) { throw new ArgumentNullException("options"); } if (this._isBeginCalledBefore) { throw new InvalidOperationException("This unit of work has started before."); } this._isBeginCalledBefore = true; //Core Process if (options.IsTransactional) { this.CurrentTransaction = new TransactionScope(options.Scope, new TransactionOptions { IsolationLevel = options.IsolationLevel, Timeout = options.Timeout }); } }
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!ActionDescriptorHelper.IsControllerActionDescriptor(context.ActionDescriptor)) { await next(); return; } var controllerActionDes = ActionDescriptorHelper.AsControllerActionDescriptor(context.ActionDescriptor); UnitOfWorkOptions options = _miCakeAspNetUowOption.RootUowOptions ?? new UnitOfWorkOptions(); if (options.Scope != UnitOfWorkScope.Suppress) { //has disableTransactionAttribute var actionMehtod = ActionDescriptorHelper.GetActionMethodInfo(context.ActionDescriptor); var hasDisableAttribute = MiCakeUowHelper.IsDisableTransaction(context.Controller.GetType()) || MiCakeUowHelper.IsDisableTransaction(actionMehtod); //has match action key word var hasMatchKeyWord = _miCakeAspNetUowOption.KeyWordToCloseTransaction.Any(keyWord => controllerActionDes.ActionName.ToUpper().StartsWith(keyWord.ToUpper())); bool needCloseTransaction = hasDisableAttribute || hasMatchKeyWord; options.Scope = needCloseTransaction ? UnitOfWorkScope.Suppress : UnitOfWorkScope.Required; } using (var unitOfWork = _unitOfWorkManager.Create(options)) { var result = await next(); if (Succeed(result)) { await unitOfWork.SaveChangesAsync(); } } }
public virtual DestinoSecuencia CrearDestinoSecuenciaSQLWithIsoSerializable(DestinoSecuencia destinoSecuencia, string codigSecuencia) { //Establecer el asilamiento a Serializable var unitOfWorkOptions = new UnitOfWorkOptions(); unitOfWorkOptions.IsolationLevel = IsolationLevel.Serializable; //transactionOptions.Timeout = TransactionManager.MaximumTimeout; DestinoSecuencia entidadGuardada = null; using (var unitOfWork = unitOfWorkManager.Begin(unitOfWorkOptions)) { //El bloque debe ser ejecuta forma sincrona AsyncHelper.RunSync(async() => { //1. Obtener la secuencia var valor = await secuenciaManager.GetNextSequenceSQL(codigSecuencia); //2. Utilizar secuencia destinoSecuencia.SecuenciaUtilizada = codigSecuencia; destinoSecuencia.Secuencia = valor; //Simular un error Random rand = new Random(); if (rand.Next(0, 3) == 0) { throw new SimulacionException(string.Format("Error en la secuencia {0}", valor)); } //3. Guardar entidadGuardada = await DestinoRepository.InsertAsync(destinoSecuencia); }); unitOfWork.Complete(); } return(entidadGuardada); }
public async Task Multiple_connections_errors_are_ignored_when_the_appropriate_option_is_specified() { var sqliteDatabaseConnectionString = new SQLiteDatabaseConnectionString("Data Source = whatever.db"); var sqliteDatabaseConnectionFactory = new SQLiteDatabaseConnectionFactory(sqliteDatabaseConnectionString); var options = new UnitOfWorkOptions { ThrowOnMultipleTransactionsAttempts = true, ThrowOnMultipleConnectionsAttempts = false }; await using var unitOfWork = new UnitOfWork(sqliteDatabaseConnectionFactory, options); await unitOfWork.OpenConnectionAsync() .ConfigureAwait(continueOnCapturedContext: false); async Task OpenConnectionAgainAsync() { await unitOfWork.OpenConnectionAsync() .ConfigureAwait(continueOnCapturedContext: false); } Assert.DoesNotThrowAsync(OpenConnectionAgainAsync); }
private void PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options) { var uow = _unitOfWorkManager.Begin(options); invocation.Proceed(); if (invocation.Method.ReturnType == typeof(Task)) { invocation.ReturnValue = InternalAsyncHelper.AwaitTaskWithPostActionAndFinally( (Task)invocation.ReturnValue, async() => await uow.CompleteAsync(), exception => uow.Dispose() ); } else //Task<TResult> { invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPostActionAndFinallyAndGetResult( invocation.Method.ReturnType.GenericTypeArguments[0], invocation.ReturnValue, async() => await uow.CompleteAsync(), (exception) => uow.Dispose() ); } }
public void Get_WithDefaults_StartsTransactionWithDefaultAndReturnsUnitOfWork() { // arrange var uowManagerLogger = new Mock <IBoltOnLogger <UnitOfWorkManager> >(); var uow = new Mock <IUnitOfWork>(); var uowFactory = new Mock <IUnitOfWorkFactory>(); var unitOfWorkOptions = new UnitOfWorkOptions(); uowFactory.Setup(u => u.Create(unitOfWorkOptions)).Returns(uow.Object); var sut = new UnitOfWorkManager(uowManagerLogger.Object, uowFactory.Object); // act var result = sut.Get(unitOfWorkOptions); // assert var uowProviderLoggerStmt = $"About to start UoW. IsolationLevel: {IsolationLevel.Serializable} " + $"TransactionTimeOut: {TransactionManager.DefaultTimeout}" + $"TransactionScopeOption: {TransactionScopeOption.Required}"; uowManagerLogger.Verify(l => l.Debug(uowProviderLoggerStmt)); // cleanup result.Dispose(); }
public MiCake_UowManager_Test() { requiredNewOptions = new UnitOfWorkOptions(null, null, UnitOfWorkLimit.RequiresNew); suppressOptions = new UnitOfWorkOptions(null, null, UnitOfWorkLimit.Suppress); }
/// <inheritdoc /> public ServicesBuilderOptions() { UowOptions = new UnitOfWorkOptions(); }
public DbContext GetOrCreateDbContext(DbContext dbcontext, UnitOfWorkOptions options) { Options = options; return(dbcontext); }
/// <summary> /// 构造获取上下文工厂 /// </summary> public SqlMasterQuery(IRepositoryWriteInfrastructure <TDbContext> _infrastructure, UnitOfWorkOptions <TDbContext> _unitOfWorkOptions) : base(_infrastructure, _unitOfWorkOptions) { }
/// <inheritdoc/> public DbContext Resolve(string connectionString, DbConnection existingConnection, UnitOfWorkOptions unitOfWorkOptions, string dbContextProviderName) { // 获取 DbContextProvider var dbContextProvider = this.GetDbContextProvider(dbContextProviderName); // 创建配置器 var dbContextConfiguration = new DbContextConfiguration(connectionString, existingConnection, unitOfWorkOptions); dbContextProvider.Configuration?.Invoke(dbContextConfiguration); // 附加模型 var model = _contextModelStorage.Get(connectionString); if (model != null) { dbContextConfiguration.DbContextOptions.UseModel(model); } // 实例化对象 var constructor = this.GetDbContextConstructor(dbContextProvider, dbContextConfiguration); var obj = constructor.Invoke(new object[] { dbContextConfiguration.DbContextOptions.Options, this._serviceProvider }); return((DbContext)obj); }
//Determine whether a new unit of work needs to be created private bool NeedCreateNewUnitOfWork(UnitOfWorkOptions options) => options.Scope switch {
public UnitOfWork(IDatabaseConnectionFactory connectionFactory, UnitOfWorkOptions unitOfWorkOptions) : this(connectionFactory, () => unitOfWorkOptions) { }
/// <summary> /// 构造获取上下文工厂 /// </summary> public SqlQueryAbstract(IRepositoryInfrastructure _infrastructure, UnitOfWorkOptions _unitOfWorkOptions) { infrastructure = _infrastructure; unitOfWorkOptions = _unitOfWorkOptions; }
public DbConnectionConfiguration(string connectionString, UnitOfWorkOptions unitOfWorkOptions) { ConnectionString = connectionString; UnitOfWorkOptions = unitOfWorkOptions; }
public virtual void Begin(UnitOfWorkOptions options) { }
public override void InitOptions(UnitOfWorkOptions options) { isBeginTransaction = true; base.InitOptions(options); }
/// <summary> /// 设置工作单元选项扩展信息中的 DbContext Provider Name /// </summary> /// <param name="unitOfWorkOptions"></param> /// <param name="name"></param> public static void SetDbContextProviderName(this UnitOfWorkOptions unitOfWorkOptions, string name) { Check.NotNullOrWhiteSpace(name, nameof(name)); unitOfWorkOptions.ExtraData[RivenUnitOfWorkEntityFrameworkCoreConsts.UnitOfWorkOptionsExtraDataDbContextProviderName] = name; }
public UnitOfWorkManager(IServiceProvider serviceProvider, IOptions <UnitOfWorkOptions> defaultOptions) { _serviceProvider = serviceProvider; _defaultOptions = defaultOptions.Value; }
public void BeginTransaction(UnitOfWorkOptions options) { _transaction = _connection.BeginTransaction(options.IsolationLevel, options.TransactionName); }
public virtual void InitOptions(UnitOfWorkOptions options) { Options = options; StartTransaction(); }
/// <inheritdoc/> public TDbContext Resolve <TDbContext>(string connectionString, DbConnection existingConnection, UnitOfWorkOptions unitOfWorkOptions, string dbContextProviderName) where TDbContext : DbContext { return(this.Resolve(connectionString, existingConnection, unitOfWorkOptions, dbContextProviderName) as TDbContext); }
public void InitOptions(UnitOfWorkOptions options) { Options = options; }
public void ChildUow_UseItSelfEvents() { var manager = ServiceProvider.GetService <IUnitOfWorkManager>() as UnitOfWorkManager; string saveInfo = ""; string rollbackInfo = ""; string disposeInfo = ""; string saveInfo2 = ""; string rollbackInfo2 = ""; string disposeInfo2 = ""; var options1 = new UnitOfWorkOptions(); options1.Events.OnCompleted += s => { saveInfo = "1"; return(Task.CompletedTask); }; options1.Events.OnRollbacked += s => { rollbackInfo = "1"; return(Task.CompletedTask); }; options1.Events.OnDispose += s => { disposeInfo = "1"; return(Task.CompletedTask); }; var options2 = new UnitOfWorkOptions(); options2.Events.OnCompleted += s => { saveInfo2 = "2"; return(Task.CompletedTask); }; options2.Events.OnRollbacked += s => { rollbackInfo2 = "2"; return(Task.CompletedTask); }; options2.Events.OnDispose += s => { disposeInfo2 = "2"; return(Task.CompletedTask); }; using (var uow1 = manager.Create(options1)) { using (var uow2 = manager.Create(options2)) { uow2.SaveChanges(); uow2.Rollback(); } uow1.SaveChanges(); uow1.Rollback(); } Assert.Equal("1", saveInfo); Assert.Equal("1", rollbackInfo); Assert.Equal("1", disposeInfo); Assert.Equal("2", saveInfo2); Assert.Equal("2", rollbackInfo2); Assert.Equal("2", disposeInfo2); }