예제 #1
0
        private TMongoDbContext CreateDbContextWithTransaction(
            IUnitOfWork unitOfWork,
            MongoUrl url,
            MongoClient client,
            IMongoDatabase database)
        {
            var transactionApiKey = $"MongoDb_{url}";
            var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as MongoDbTransactionApi;
            var dbContext         = unitOfWork.ServiceProvider.GetRequiredService <TMongoDbContext>();

            if (activeTransaction?.SessionHandle == null)
            {
                var session = client.StartSession();

                if (unitOfWork.Options.Timeout.HasValue)
                {
                    session.AdvanceOperationTime(new BsonTimestamp(unitOfWork.Options.Timeout.Value));
                }

                session.StartTransaction();

                unitOfWork.AddTransactionApi(
                    transactionApiKey,
                    new MongoDbTransactionApi(session)
                    );

                dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, session);
            }
            else
            {
                dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, activeTransaction.SessionHandle);
            }

            return(dbContext);
        }
예제 #2
0
    private async Task <TMongoDbContext> CreateDbContextWithTransactionAsync(
        IUnitOfWork unitOfWork,
        MongoUrl url,
        MongoClient client,
        IMongoDatabase database,
        CancellationToken cancellationToken = default)
    {
        var transactionApiKey = $"MongoDb_{url}";
        var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as MongoDbTransactionApi;
        var dbContext         = unitOfWork.ServiceProvider.GetRequiredService <TMongoDbContext>();

        if (activeTransaction?.SessionHandle == null)
        {
            var session = await client.StartSessionAsync(cancellationToken : GetCancellationToken(cancellationToken));

            if (unitOfWork.Options.Timeout.HasValue)
            {
                session.AdvanceOperationTime(new BsonTimestamp(unitOfWork.Options.Timeout.Value));
            }

            try
            {
                session.StartTransaction();
            }
            catch (NotSupportedException e)
            {
                Logger.LogError("The current MongoDB database does not support transactions, All operations will be performed in non-transactions, This may cause errors.");
                Logger.LogException(e);

                dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, null);
                return(dbContext);
            }

            unitOfWork.AddTransactionApi(
                transactionApiKey,
                new MongoDbTransactionApi(
                    session,
                    _cancellationTokenProvider
                    )
                );

            dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, session);
        }
        else
        {
            dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, activeTransaction.SessionHandle);
        }

        return(dbContext);
    }
    private TMongoDbContext CreateDbContextWithTransaction(
        IUnitOfWork unitOfWork,
        MongoUrl url,
        MongoClient client,
        IMongoDatabase database)
    {
        var transactionApiKey = $"MongoDb_{url}";
        var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as MongoDbTransactionApi;
        var dbContext         = unitOfWork.ServiceProvider.GetRequiredService <TMongoDbContext>();

        if (activeTransaction?.SessionHandle == null)
        {
            var session = client.StartSession();

            if (unitOfWork.Options.Timeout.HasValue)
            {
                session.AdvanceOperationTime(new BsonTimestamp(unitOfWork.Options.Timeout.Value));
            }

            try
            {
                session.StartTransaction();
            }
            catch (NotSupportedException e)
            {
                Logger.LogError(TransactionsNotSupportedErrorMessage);
                Logger.LogException(e);

                dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, null);
                return(dbContext);
            }

            unitOfWork.AddTransactionApi(
                transactionApiKey,
                new MongoDbTransactionApi(
                    session,
                    _cancellationTokenProvider
                    )
                );

            dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, session);
        }
        else
        {
            dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, activeTransaction.SessionHandle);
        }

        return(dbContext);
    }
예제 #4
0
        private async Task <TDbContext> CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork)
        {
            var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}";
            var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as EfCoreTransactionApi;

            if (activeTransaction == null)
            {
                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

                var dbTransaction = unitOfWork.Options.IsolationLevel.HasValue
                    ? await dbContext.Database.BeginTransactionAsync(unitOfWork.Options.IsolationLevel.Value, GetCancellationToken())
                    : await dbContext.Database.BeginTransactionAsync(GetCancellationToken());

                unitOfWork.AddTransactionApi(
                    transactionApiKey,
                    new EfCoreTransactionApi(
                        dbTransaction,
                        dbContext,
                        _cancellationTokenProvider
                        )
                    );

                return(dbContext);
            }
            else
            {
                DbContextCreationContext.Current.ExistingConnection = activeTransaction.DbContextTransaction.GetDbTransaction().Connection;

                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

                if (dbContext.As <DbContext>().HasRelationalTransactionManager())
                {
                    await dbContext.Database.UseTransactionAsync(activeTransaction.DbContextTransaction.GetDbTransaction(), GetCancellationToken());
                }
                else
                {
                    /* No need to store the returning IDbContextTransaction for non-relational databases
                     * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance.
                     */
                    await dbContext.Database.BeginTransactionAsync(GetCancellationToken());
                }

                activeTransaction.AttendedDbContexts.Add(dbContext);

                return(dbContext);
            }
        }
        public TDbContext CreateDbContextWithTransaction <TDbContext>(IUnitOfWork unitOfWork)
            where TDbContext : AbpDbContext
        {
            var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}";
            var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as EfCoreTransactionApi;

            if (activeTransaction == null)
            {
                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

                var dbtransaction = unitOfWork.Options.IsolationLevel.HasValue
                    ? dbContext.Database.BeginTransaction(unitOfWork.Options.IsolationLevel.Value)
                    : dbContext.Database.BeginTransaction();

                unitOfWork.AddTransactionApi(
                    transactionApiKey,
                    new EfCoreTransactionApi(
                        dbtransaction,
                        dbContext
                        )
                    );

                return(dbContext);
            }
            else
            {
                DbContextCreationContext.Current.ExistingConnection = activeTransaction.DbContextTransaction.GetDbTransaction().Connection;

                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

                if (dbContext.As <DbContext>().Database.GetService <IDbContextTransactionManager>() is IRelationalTransactionManager)
                {
                    dbContext.Database.UseTransaction(activeTransaction.DbContextTransaction.GetDbTransaction());
                }
                else
                {
                    dbContext.Database.BeginTransaction(); //TODO: Why not using the new created transaction?
                }

                activeTransaction.AttendedDbContexts.Add(dbContext);

                return(dbContext);
            }
        }
예제 #6
0
        private async Task <TDbContext> CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork)
        {
            var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}";
            var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as EfCoreTransactionApi;

            if (activeTransaction == null)
            {
                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

                var dbTransaction = unitOfWork.Options.IsolationLevel.HasValue
                    ? await dbContext.Database.BeginTransactionAsync(unitOfWork.Options.IsolationLevel.Value, GetCancellationToken())
                    : await dbContext.Database.BeginTransactionAsync(GetCancellationToken());

                unitOfWork.AddTransactionApi(
                    transactionApiKey,
                    new EfCoreTransactionApi(
                        dbTransaction,
                        dbContext
                        )
                    );

                return(dbContext);
            }
            else
            {
                DbContextCreationContext.Current.ExistingConnection = activeTransaction.DbContextTransaction.GetDbTransaction().Connection;

                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

                if (dbContext.As <DbContext>().HasRelationalTransactionManager())
                {
                    await dbContext.Database.UseTransactionAsync(activeTransaction.DbContextTransaction.GetDbTransaction(), GetCancellationToken());
                }
                else
                {
                    await dbContext.Database.BeginTransactionAsync(GetCancellationToken()); //TODO: Why not using the new created transaction?
                }

                activeTransaction.AttendedDbContexts.Add(dbContext);

                return(dbContext);
            }
        }
        private DbContextBase CreateDbContextWithTransaction(IUnitOfWork unitOfWork)
        {
            var activeTransaction = unitOfWork.FindTransactionApi() as TransactionApi;

            if (activeTransaction == null)
            {
                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <DbContextBase>();

                var dbtransaction = unitOfWork.Options.IsolationLevel.HasValue
                    ? dbContext.Database.BeginTransaction(unitOfWork.Options.IsolationLevel.Value)
                    : dbContext.Database.BeginTransaction();

                unitOfWork.AddTransactionApi(
                    new TransactionApi(
                        dbtransaction,
                        dbContext
                        )
                    );

                return(dbContext);
            }
            else
            {
                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <DbContextBase>();

                if (dbContext.HasRelationalTransactionManager())
                {
                    dbContext.Database.UseTransaction(activeTransaction.DbContextTransaction.GetDbTransaction());
                }
                else
                {
                    dbContext.Database.BeginTransaction(); //TODO: Why not using the new created transaction?
                }

                activeTransaction.AttendedDbContexts.Add(dbContext);

                return(dbContext);
            }
        }
        private IDatabase CreateDatabase(IUnitOfWork unitOfWork)
        {
            var creationContext = new DatabaseCreationContext();

            using (DatabaseCreationContext.Use(creationContext))
            {
                var database = CreateDatabase();
                if (unitOfWork.Options.IsTransactional)
                {
                    var dbtransaction = unitOfWork.Options.IsolationLevel.HasValue
                    ? database.Connection.BeginTransaction(unitOfWork.Options.IsolationLevel.Value)
                    : database.Connection.BeginTransaction();

                    unitOfWork.AddTransactionApi(
                        new TransactionApi(
                            dbtransaction,
                            database
                            )
                        );
                }

                return(database);
            }
        }
예제 #9
0
 public void AddTransactionApi(string key, ITransactionApi api)
 {
     _parent.AddTransactionApi(key, api);
 }
예제 #10
0
    private async Task <TDbContext> CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork)
    {
        var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}";
        var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as EfCoreTransactionApi;

        if (activeTransaction == null)
        {
            var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

            try
            {
                var dbTransaction = unitOfWork.Options.IsolationLevel.HasValue
                    ? await dbContext.Database.BeginTransactionAsync(unitOfWork.Options.IsolationLevel.Value, GetCancellationToken())
                    : await dbContext.Database.BeginTransactionAsync(GetCancellationToken());

                unitOfWork.AddTransactionApi(
                    transactionApiKey,
                    new EfCoreTransactionApi(
                        dbTransaction,
                        dbContext,
                        _cancellationTokenProvider
                        )
                    );
            }
            catch (Exception e) when(e is InvalidOperationException || e is NotSupportedException)
            {
                Logger.LogError(TransactionsNotSupportedErrorMessage);
                Logger.LogException(e);

                return(dbContext);
            }

            return(dbContext);
        }
        else
        {
            DbContextCreationContext.Current.ExistingConnection = activeTransaction.DbContextTransaction.GetDbTransaction().Connection;

            var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

            if (dbContext.As <DbContext>().HasRelationalTransactionManager())
            {
                if (dbContext.Database.GetDbConnection() == DbContextCreationContext.Current.ExistingConnection)
                {
                    await dbContext.Database.UseTransactionAsync(activeTransaction.DbContextTransaction.GetDbTransaction(), GetCancellationToken());
                }
                else
                {
                    try
                    {
                        /* User did not re-use the ExistingConnection and we are starting a new transaction.
                         * EfCoreTransactionApi will check the connection string match and separately
                         * commit/rollback this transaction over the DbContext instance. */
                        if (unitOfWork.Options.IsolationLevel.HasValue)
                        {
                            await dbContext.Database.BeginTransactionAsync(
                                unitOfWork.Options.IsolationLevel.Value,
                                GetCancellationToken()
                                );
                        }
                        else
                        {
                            await dbContext.Database.BeginTransactionAsync(
                                GetCancellationToken()
                                );
                        }
                    }
                    catch (Exception e) when(e is InvalidOperationException || e is NotSupportedException)
                    {
                        Logger.LogError(TransactionsNotSupportedErrorMessage);
                        Logger.LogException(e);

                        return(dbContext);
                    }
                }
            }
            else
            {
                try
                {
                    /* No need to store the returning IDbContextTransaction for non-relational databases
                     * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance.
                     */
                    await dbContext.Database.BeginTransactionAsync(GetCancellationToken());
                }
                catch (Exception e) when(e is InvalidOperationException || e is NotSupportedException)
                {
                    Logger.LogError(TransactionsNotSupportedErrorMessage);
                    Logger.LogException(e);

                    return(dbContext);
                }
            }

            activeTransaction.AttendedDbContexts.Add(dbContext);

            return(dbContext);
        }
    }
예제 #11
0
        private TDbContext CreateDbContextWithTransaction(IUnitOfWork unitOfWork)
        {
            var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}";
            var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as EfCoreTransactionApi;

            if (activeTransaction == null)
            {
                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

                var dbtransaction = unitOfWork.Options.IsolationLevel.HasValue
                    ? dbContext.Database.BeginTransaction(unitOfWork.Options.IsolationLevel.Value)
                    : dbContext.Database.BeginTransaction();

                unitOfWork.AddTransactionApi(
                    transactionApiKey,
                    new EfCoreTransactionApi(
                        dbtransaction,
                        dbContext,
                        _cancellationTokenProvider
                        )
                    );

                return(dbContext);
            }
            else
            {
                DbContextCreationContext.Current.ExistingConnection = activeTransaction.DbContextTransaction.GetDbTransaction().Connection;

                var dbContext = unitOfWork.ServiceProvider.GetRequiredService <TDbContext>();

                if (dbContext.As <DbContext>().HasRelationalTransactionManager())
                {
                    if (dbContext.Database.GetDbConnection() == DbContextCreationContext.Current.ExistingConnection)
                    {
                        dbContext.Database.UseTransaction(activeTransaction.DbContextTransaction.GetDbTransaction());
                    }
                    else
                    {
                        /* User did not re-use the ExistingConnection and we are starting a new transaction.
                         * EfCoreTransactionApi will check the connection string match and separately
                         * commit/rollback this transaction over the DbContext instance. */
                        if (unitOfWork.Options.IsolationLevel.HasValue)
                        {
                            dbContext.Database.BeginTransaction(unitOfWork.Options.IsolationLevel.Value);
                        }
                        else
                        {
                            dbContext.Database.BeginTransaction();
                        }
                    }
                }
                else
                {
                    /* No need to store the returning IDbContextTransaction for non-relational databases
                     * since EfCoreTransactionApi will handle the commit/rollback over the DbContext instance.
                     */
                    dbContext.Database.BeginTransaction();
                }

                activeTransaction.AttendedDbContexts.Add(dbContext);

                return(dbContext);
            }
        }
예제 #12
0
 public void AddTransactionApi(ITransactionApi api)
 {
     _parent.AddTransactionApi(api);
 }