public void Cloning_the_interception_context_preserves_contextual_information_but_not_mutable_state()
        {
            var objectContext = new ObjectContext();
            var dbContext = DbContextMockHelper.CreateDbContext(objectContext);

            var interceptionContext = new BeginTransactionInterceptionContext();

            var mutableData = ((IDbMutableInterceptionContext<DbTransaction>)interceptionContext).MutableData;
            var transaction = new Mock<DbTransaction>().Object;
            mutableData.SetExecuted(transaction);
            mutableData.SetExceptionThrown(new Exception("Cheez Whiz"));

            interceptionContext = interceptionContext
                .WithDbContext(dbContext)
                .WithObjectContext(objectContext)
                .WithIsolationLevel(IsolationLevel.RepeatableRead)
                .AsAsync();

            interceptionContext = new BeginTransactionInterceptionContext(interceptionContext);

            Assert.Equal(new[] { objectContext }, interceptionContext.ObjectContexts);
            Assert.Equal(new[] { dbContext }, interceptionContext.DbContexts);
            Assert.True(interceptionContext.IsAsync);
            Assert.Equal(IsolationLevel.RepeatableRead, interceptionContext.IsolationLevel);

            Assert.Null(interceptionContext.Result);
            Assert.Null(interceptionContext.OriginalResult);
            Assert.Null(interceptionContext.Exception);
            Assert.Null(interceptionContext.OriginalException);
            Assert.False(interceptionContext.IsExecutionSuppressed);
        }
示例#2
0
        public void BeganTransaction(DbConnection connection,
                                     BeginTransactionInterceptionContext interceptionContext)
        {
            var context = EFProfilerContextProvider.GetLoggedDbConnection(connection, interceptionContext);

            _profiler.TransactionBegan(connection, context);
        }
示例#3
0
        /// <summary>
        /// Stores the tracking information for the new transaction to the database in the same transaction.
        /// </summary>
        /// <param name="connection">The connection that began the transaction.</param>
        /// <param name="interceptionContext">Contextual information associated with the call.</param>
        /// <seealso cref="M:System.Data.Entity.Infrastructure.Interception.IDbConnectionInterceptor.BeganTransaction(System.Data.Common.DbConnection,System.Data.Entity.Infrastructure.Interception.BeginTransactionInterceptionContext)" />
        public override void BeganTransaction(
            DbConnection connection,
            BeginTransactionInterceptionContext interceptionContext)
        {
            if (this.TransactionContext == null || !this.MatchesParentContext(connection, (DbInterceptionContext)interceptionContext) || interceptionContext.Result == null)
            {
                return;
            }
            Guid          transactionId = Guid.NewGuid();
            bool          flag1         = false;
            bool          flag2         = false;
            ObjectContext objectContext = ((IObjectContextAdapter)this.TransactionContext).ObjectContext;

            ((EntityConnection)objectContext.Connection).UseStoreTransaction(interceptionContext.Result);
            while (!flag1)
            {
                TransactionRow entity = new TransactionRow()
                {
                    Id           = transactionId,
                    CreationTime = DateTime.Now
                };
                this._transactions.Add(interceptionContext.Result, entity);
                this.TransactionContext.Transactions.Add(entity);
                try
                {
                    objectContext.SaveChangesInternal(SaveOptions.AcceptAllChangesAfterSave, true);
                    flag1 = true;
                }
                catch (UpdateException ex1)
                {
                    this._transactions.Remove(interceptionContext.Result);
                    this.TransactionContext.Entry <TransactionRow>(entity).State = EntityState.Detached;
                    if (flag2)
                    {
                        throw;
                    }
                    else
                    {
                        try
                        {
                            if (this.TransactionContext.Transactions.AsNoTracking <TransactionRow>().WithExecutionStrategy <TransactionRow>((IDbExecutionStrategy) new DefaultExecutionStrategy()).FirstOrDefault <TransactionRow>((Expression <Func <TransactionRow, bool> >)(t => t.Id == transactionId)) != null)
                            {
                                transactionId = Guid.NewGuid();
                            }
                            else
                            {
                                throw;
                            }
                        }
                        catch (EntityCommandExecutionException ex2)
                        {
                            this.TransactionContext.Database.Initialize(true);
                            flag2 = true;
                        }
                    }
                }
            }
        }
		public void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
		{
			if (connection is FbConnection
				&& interceptionContext.IsolationLevel == IsolationLevel.Serializable
				&& IsInMigrations())
			{
				interceptionContext.Result = connection.BeginTransaction(IsolationLevel.ReadCommitted);
			}
		}
 public void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     if (connection is FbConnection &&
         interceptionContext.IsolationLevel == IsolationLevel.Serializable &&
         IsInMigrations())
     {
         interceptionContext.Result = connection.BeginTransaction(IsolationLevel.ReadCommitted);
     }
 }
            public void BeganTransaction_does_not_fail_if_exception_thrown_such_that_there_is_no_transaction()
            {
                var context = MockHelper.CreateMockObjectContext <object>();
                var handler = new CommitFailureHandler();

                handler.Initialize(context);

                var interceptionContext = new BeginTransactionInterceptionContext().WithObjectContext(context);

                Assert.DoesNotThrow(() => handler.BeganTransaction(new Mock <DbConnection>().Object, interceptionContext));
            }
        /// <summary>
        /// Sends <see cref="IDbConnectionInterceptor.BeginningTransaction" /> and
        /// <see cref="IDbConnectionInterceptor.BeganTransaction" /> to any <see cref="IDbConnectionInterceptor" />
        /// registered on <see cref="DbInterception" /> before/after making a
        /// call to <see cref="DbConnection.BeginTransaction(IsolationLevel)" />.
        /// </summary>
        /// <remarks>
        /// Note that the result of executing the command is returned by this method. The result is not available
        /// in the interception context passed into this method since the interception context is cloned before
        /// being passed to interceptors.
        /// </remarks>
        /// <param name="connection">The connection on which the operation will be executed.</param>
        /// <param name="interceptionContext">Optional information about the context of the call being made.</param>
        /// <returns>The result of the operation, which may have been modified by interceptors.</returns>
        public virtual DbTransaction BeginTransaction(
            DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
        {
            Check.NotNull(connection, "connection");
            Check.NotNull(interceptionContext, "interceptionContext");

            return InternalDispatcher.Dispatch(
                connection,
                (t, c) => t.BeginTransaction(c.IsolationLevel),
                new BeginTransactionInterceptionContext(interceptionContext),
                (i, t, c) => i.BeginningTransaction(t, c),
                (i, t, c) => i.BeganTransaction(t, c));
        }
 /// <summary>
 /// Called after <see cref="DbConnection.BeginTransaction(Data.IsolationLevel)" /> is invoked.
 /// The default implementation of this method filters by <see cref="DbContext" /> set into
 /// <see cref="Context" />, if any, and then logs the event.
 /// </summary>
 /// <param name="connection">The connection that began the transaction.</param>
 /// <param name="interceptionContext">Contextual information associated with the call.</param>
 public virtual void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     if (ShouldLog(interceptionContext))
     {
         if (interceptionContext.Exception != null)
         {
             LogError(interceptionContext.Exception, "Failed to start transaction at {now} with error: {error}", DateTimeOffset.Now, interceptionContext.Exception.Message);
         }
         else
         {
             LogInformation("Started transaction at {now},", DateTimeOffset.Now);
         }
     }
 }
        public void Initially_has_no_state()
        {
            var interceptionContext = new BeginTransactionInterceptionContext();

            Assert.Empty(interceptionContext.DbContexts);
            Assert.Null(interceptionContext.Exception);
            Assert.False(interceptionContext.IsAsync);
            Assert.False(interceptionContext.IsExecutionSuppressed);
            Assert.Equal(IsolationLevel.Unspecified, interceptionContext.IsolationLevel);
            Assert.Empty(interceptionContext.ObjectContexts);
            Assert.Null(interceptionContext.OriginalException);
            Assert.Null(interceptionContext.OriginalResult);
            Assert.Null(interceptionContext.Result);
            Assert.Equal((TaskStatus)0, interceptionContext.TaskStatus);
        }
        public void BeginTransaction_executes_operation_and_dispatches_to_interceptors()
        {
            var mockConnection = new Mock<DbConnection>();
            var mockInterceptor = new Mock<IDbConnectionInterceptor>();
            var dispatcher = new DbConnectionDispatcher();
            var internalDispatcher = dispatcher.InternalDispatcher;
            internalDispatcher.Add(mockInterceptor.Object);

            var interceptionContext = new BeginTransactionInterceptionContext().WithIsolationLevel(IsolationLevel.Serializable);
            dispatcher.BeginTransaction(mockConnection.Object, interceptionContext);

            mockConnection.Protected().Verify<DbTransaction>("BeginDbTransaction", Times.Once(), IsolationLevel.Serializable);
            mockInterceptor.Verify(m => m.BeginningTransaction(mockConnection.Object, It.IsAny<BeginTransactionInterceptionContext>()), Times.Once());
            mockInterceptor.Verify(m => m.BeganTransaction(mockConnection.Object, It.IsAny<BeginTransactionInterceptionContext>()), Times.Once());
        }
示例#11
0
 /// <summary>
 /// Called after DbConnection.BeginTransaction(Data.IsolationLevel) is invoked.
 /// The default implementation of this method filters by <see cref="DbContext" /> set into
 /// <see cref="Context" />, if any, and then logs the event.
 /// </summary>
 /// <param name="connection">The connection that began the transaction.</param>
 /// <param name="interceptionContext">Contextual information associated with the call.</param>
 public virtual void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     if (ShouldLog(interceptionContext))
     {
         if (interceptionContext.Exception != null)
         {
             LogError(
                 interceptionContext.Exception,
                 $"Failed to start transaction with error: {interceptionContext.Exception.Message}");
         }
         else
         {
             LogInformation("Started transaction {0}", connection.GetHashCode());
         }
     }
 }
        public void Commited_wraps_exceptions_for_known_transactions()
        {
            var context = Core.Objects.MockHelper.CreateMockObjectContext<object>();
            var handler = new DefaultTransactionHandler();
            handler.Initialize(context);
            var mockTransaction = new Mock<DbTransaction>().Object;

            var beginTransactionInterceptionContext = new BeginTransactionInterceptionContext();
            beginTransactionInterceptionContext.Result = mockTransaction;

            handler.BeganTransaction(handler.Connection, beginTransactionInterceptionContext);

            var interceptionContext = new DbTransactionInterceptionContext().WithConnection(handler.Connection);
            interceptionContext.Exception = new Exception();
            handler.Committed(mockTransaction, interceptionContext);

            Assert.IsType<CommitFailedException>(interceptionContext.Exception);
        }
        public void BeganTransaction_does_not_record_transaction_if_connection_does_not_match()
        {
            var context = Core.Objects.MockHelper.CreateMockObjectContext<object>();
            var handler = new DefaultTransactionHandler();
            handler.Initialize(context);
            var mockTransaction = new Mock<DbTransaction>().Object;

            var beginTransactionInterceptionContext = new BeginTransactionInterceptionContext();
            beginTransactionInterceptionContext.Result = mockTransaction;

            handler.BeganTransaction(new Mock<DbConnection>().Object, beginTransactionInterceptionContext);

            var interceptionContext = new DbTransactionInterceptionContext();
            interceptionContext.Exception = new Exception();
            handler.Committed(mockTransaction, interceptionContext);

            Assert.IsNotType<CommitFailedException>(interceptionContext.Exception);
        }
        public void BeganTransaction_does_not_record_transaction_if_connection_does_not_match()
        {
            var context = Core.Objects.MockHelper.CreateMockObjectContext <object>();
            var handler = new DefaultTransactionHandler();

            handler.Initialize(context);
            var mockTransaction = new Mock <DbTransaction>().Object;

            var beginTransactionInterceptionContext = new BeginTransactionInterceptionContext();

            beginTransactionInterceptionContext.Result = mockTransaction;

            handler.BeganTransaction(new Mock <DbConnection>().Object, beginTransactionInterceptionContext);

            var interceptionContext = new DbTransactionInterceptionContext();

            interceptionContext.Exception = new Exception();
            handler.Committed(mockTransaction, interceptionContext);

            Assert.IsNotType <CommitFailedException>(interceptionContext.Exception);
        }
        public void Committed_wraps_exceptions_for_known_transactions()
        {
            var context = Core.Objects.MockHelper.CreateMockObjectContext <object>();
            var handler = new DefaultTransactionHandler();

            handler.Initialize(context);
            var mockTransaction = new Mock <DbTransaction>().Object;

            var beginTransactionInterceptionContext = new BeginTransactionInterceptionContext();

            beginTransactionInterceptionContext.Result = mockTransaction;

            handler.BeganTransaction(handler.Connection, beginTransactionInterceptionContext);

            var interceptionContext = new DbTransactionInterceptionContext().WithConnection(handler.Connection);

            interceptionContext.Exception = new Exception();
            handler.Committed(mockTransaction, interceptionContext);

            Assert.IsType <CommitFailedException>(interceptionContext.Exception);
        }
示例#16
0
        private void ExecuteStatementsWithinNewTransaction(
            IEnumerable <MigrationStatement> migrationStatements,
            DbConnection connection,
            DbInterceptionContext interceptionContext)
        {
            BeginTransactionInterceptionContext interceptionContext1 = new BeginTransactionInterceptionContext(interceptionContext).WithIsolationLevel(IsolationLevel.Serializable);
            DbTransaction transaction = (DbTransaction)null;

            try
            {
                transaction = DbInterception.Dispatch.Connection.BeginTransaction(connection, interceptionContext1);
                this.ExecuteStatementsWithinTransaction(migrationStatements, transaction, interceptionContext);
                DbInterception.Dispatch.Transaction.Commit(transaction, interceptionContext);
            }
            finally
            {
                if (transaction != null)
                {
                    DbInterception.Dispatch.Transaction.Dispose(transaction, interceptionContext);
                }
            }
        }
 public abstract void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext);
示例#18
0
 public void BeginningTransaction(DbConnection connection,
                                  BeginTransactionInterceptionContext interceptionContext)
 {
     Debug.WriteLine("Transaction BeginningTransaction.");
 }
 public void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
 }
示例#20
0
 public void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     interceptionContext = interceptionContext.WithIsolationLevel(IsolationLevel.Snapshot);
 }
示例#21
0
        /// <summary>
        /// Stores the tracking information for the new transaction to the database in the same transaction.
        /// </summary>
        /// <param name="connection">The connection that began the transaction.</param>
        /// <param name="interceptionContext">Contextual information associated with the call.</param>
        /// <seealso cref="IDbConnectionInterceptor.BeganTransaction" />
        public override void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
        {
            if (TransactionContext == null ||
                !MatchesParentContext(connection, interceptionContext))
            {
                return;
            }

            var transactionId         = Guid.NewGuid();
            var savedSuccesfully      = false;
            var reinitializedDatabase = false;

            while (!savedSuccesfully)
            {
                Debug.Assert(!_transactions.ContainsKey(interceptionContext.Result), "The transaction has already been registered");
                var transactionRow = new TransactionRow {
                    Id = transactionId, CreationTime = DateTime.Now
                };
                _transactions.Add(interceptionContext.Result, transactionRow);
                TransactionContext.Transactions.Add(transactionRow);

                var objectContext = ((IObjectContextAdapter)TransactionContext).ObjectContext;
                ((EntityConnection)objectContext.Connection).UseStoreTransaction(interceptionContext.Result);
                try
                {
                    objectContext.SaveChanges(SaveOptions.DetectChangesBeforeSave, executeInExistingTransaction: true);
                    savedSuccesfully = true;
                }
                catch (UpdateException)
                {
                    _transactions.Remove(interceptionContext.Result);
                    TransactionContext.Transactions.Remove(transactionRow);

                    if (reinitializedDatabase)
                    {
                        throw;
                    }

                    try
                    {
                        var existingTransaction =
                            TransactionContext.Transactions
                            .AsNoTracking()
                            .WithExecutionStrategy(new DefaultExecutionStrategy())
                            .FirstOrDefault(t => t.Id == transactionId);

                        if (existingTransaction != null)
                        {
                            transactionId = Guid.NewGuid();
                            Debug.Assert(false, "Duplicate GUID! this should never happen");
                        }
                    }
                    catch (EntityCommandExecutionException)
                    {
                        // The necessary tables are not present.
                        // This can happen if the database was deleted after TransactionContext has been initialized
                        TransactionContext.Database.Initialize(force: true);

                        reinitializedDatabase = true;
                    }

                    interceptionContext.Result.Rollback();
                    interceptionContext.Result = connection.BeginTransaction(interceptionContext.IsolationLevel);
                }
            }
        }
示例#22
0
 /// <summary>
 /// 启动了事务
 /// </summary>
 public override void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     base.BeganTransaction(connection, interceptionContext);
     Write(Environment.NewLine);
 }
示例#23
0
        private void ExecuteStatementsInternal(IEnumerable<MigrationStatement> migrationStatements, DbConnection connection)
        {
            DebugCheck.NotNull(migrationStatements);
            DebugCheck.NotNull(connection);

            var context = _usersContext ?? _usersContextInfo.CreateInstance();

            var interceptionContext = new DbInterceptionContext();
            interceptionContext = interceptionContext.WithDbContext(context);

            if (DbInterception.Dispatch.Connection.GetState(connection, interceptionContext) == ConnectionState.Broken)
            {
                DbInterception.Dispatch.Connection.Close(connection, interceptionContext);
            }

            if (DbInterception.Dispatch.Connection.GetState(connection, interceptionContext) == ConnectionState.Closed)
            {
                DbInterception.Dispatch.Connection.Open(connection, interceptionContext);
            }

            TransactionHandler transactionHandler = null;
            try
            {
                if (!(context is TransactionContext))
                {
                    var providerInvariantName =
                        DbConfiguration.DependencyResolver.GetService<IProviderInvariantName>(
                            DbProviderServices.GetProviderFactory(connection))
                            .Name;

                    var dataSource = DbInterception.Dispatch.Connection.GetDataSource(connection, interceptionContext);

                    var transactionHandlerFactory = DbConfiguration.DependencyResolver.GetService<Func<TransactionHandler>>(
                        new ExecutionStrategyKey(providerInvariantName, dataSource));

                    if (transactionHandlerFactory != null)
                    {
                        transactionHandler = transactionHandlerFactory();
                        transactionHandler.Initialize(context, connection);
                    }
                }

                var beginTransactionInterceptionContext = new BeginTransactionInterceptionContext(interceptionContext)
                    .WithIsolationLevel(IsolationLevel.Serializable);

                DbTransaction transaction = null;
                try
                {
                    transaction = DbInterception.Dispatch.Connection.BeginTransaction(
                        connection,
                        beginTransactionInterceptionContext);

                    ExecuteStatementsInternal(migrationStatements, transaction, interceptionContext);

                    DbInterception.Dispatch.Transaction.Commit(transaction, interceptionContext);
                    _committedStatements = true;
                }
                finally
                {
                    if (transaction != null)
                    {
                        DbInterception.Dispatch.Transaction.Dispose(transaction, interceptionContext);
                    }
                }
            }
            finally
            {
                if (transactionHandler != null)
                {
                    transactionHandler.Dispose();
                }

                if (_usersContext == null)
                {
                    context.Dispose();
                }
            }
        }
示例#24
0
 public void BeganTransaction(DbConnection connection,
                              BeginTransactionInterceptionContext interceptionContext)
 {
     var context = EFProfilerContextProvider.GetLoggedDbConnection(connection, interceptionContext);
     _profiler.TransactionBegan(connection, context);
 }
示例#25
0
        /// <summary>
        /// Stores the tracking information for the new transaction to the database in the same transaction.
        /// </summary>
        /// <param name="connection">The connection that began the transaction.</param>
        /// <param name="interceptionContext">Contextual information associated with the call.</param>
        /// <seealso cref="IDbConnectionInterceptor.BeganTransaction" />
        public override void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
        {
            if (TransactionContext == null
                || !MatchesParentContext(connection, interceptionContext)
                || interceptionContext.Result == null)
            {
                return;
            }

            var transactionId = Guid.NewGuid();
            var savedSuccesfully = false;
            var reinitializedDatabase = false;
            var objectContext = ((IObjectContextAdapter)TransactionContext).ObjectContext;
            ((EntityConnection)objectContext.Connection).UseStoreTransaction(interceptionContext.Result);
            while (!savedSuccesfully)
            {
                Debug.Assert(!_transactions.ContainsKey(interceptionContext.Result), "The transaction has already been registered");
                var transactionRow = new TransactionRow { Id = transactionId, CreationTime = DateTime.Now };
                _transactions.Add(interceptionContext.Result, transactionRow);

                TransactionContext.Transactions.Add(transactionRow);
                try
                {
                    objectContext.SaveChangesInternal(SaveOptions.AcceptAllChangesAfterSave, executeInExistingTransaction: true);
                    savedSuccesfully = true;
                }
                catch (UpdateException)
                {
                    _transactions.Remove(interceptionContext.Result);
                    TransactionContext.Entry(transactionRow).State = EntityState.Detached;

                    if (reinitializedDatabase)
                    {
                        throw;
                    }

                    try
                    {
                        var existingTransaction =
                            TransactionContext.Transactions
                                .AsNoTracking()
                                .WithExecutionStrategy(new DefaultExecutionStrategy())
                                .FirstOrDefault(t => t.Id == transactionId);

                        if (existingTransaction != null)
                        {
                            transactionId = Guid.NewGuid();
                            Debug.Assert(false, "Duplicate GUID! this should never happen");
                        }
                        else
                        {
                            // Unknown exception cause
                            throw;
                        }
                    }
                    catch (EntityCommandExecutionException)
                    {
                        // The necessary tables are not present.
                        // This can happen if the database was deleted after TransactionContext has been initialized
                        TransactionContext.Database.Initialize(force: true);

                        reinitializedDatabase = true;
                    }
                }
            }
        }
 /// <summary>
 /// 在开启一个数据库事务动作执行前瞬间触发。
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="interceptionContext"></param>
 public virtual void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
 }
 public void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     //throw new NotImplementedException();
 }
 /// <summary>
 /// 在开启一个数据库事务动作执行前瞬间触发。当开始事务操作时将数据库连接字符串更新至 Master 数据库。
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="interceptionContext"></param>
 public override void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     this.UpdateConnectionStringIfNeed(connection, this.Config.UsableMasterConnectionString, interceptionContext.DbContexts);
 }
示例#29
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="interceptionContext"></param>
 public override void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     //base.BeganTransaction( connection, interceptionContext );
 }
        public static DbConnectionContext GetLoggedDbConnection(IDbConnection connection, BeginTransactionInterceptionContext interceptionContext)
        {
            var context = new DbConnectionContext
            {
                IsAsync          = interceptionContext.IsAsync,
                IsCanceled       = interceptionContext.TaskStatus.HasFlag(TaskStatus.Canceled),
                Exception        = interceptionContext.OriginalException ?? interceptionContext.Exception,
                ConnectionString = connection.ConnectionString,
                TransactionId    =
                    interceptionContext.Result == null
                        ? (int?)null
                        : UniqueIdExtensions <DbTransaction> .GetUniqueId(interceptionContext.Result).ToInt(),
                IsolationLevel =
                    interceptionContext.Result == null ? IsolationLevel.Unspecified : interceptionContext.Result.IsolationLevel
            };

            setBaseInfo(interceptionContext, context);
            return(context);
        }
示例#31
0
 /// <summary>
 /// Can be implemented in a derived class.
 /// </summary>
 /// <param name="connection">The connection beginning the transaction.</param>
 /// <param name="interceptionContext">Contextual information associated with the call.</param>
 /// <seealso cref="IDbConnectionInterceptor.BeginningTransaction"/>
 public virtual void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
 }
            public void BeganTransaction_does_not_fail_if_exception_thrown_such_that_there_is_no_transaction()
            {
                var context = MockHelper.CreateMockObjectContext<object>();
                var handler = new CommitFailureHandler();
                handler.Initialize(context);

                var interceptionContext = new BeginTransactionInterceptionContext().WithObjectContext(context);

                Assert.DoesNotThrow(() => handler.BeganTransaction(new Mock<DbConnection>().Object, interceptionContext));
            }
示例#33
0
 public override void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     UpdateConnectionStringIfNeed(connection, MasterConnectionString);
 }
示例#34
0
 public override void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     //不记录事务开启信息
 }
        /// <summary>
        /// Begins a database transaction
        /// </summary>
        /// <param name="isolationLevel"> The isolation level of the transaction </param>
        /// <returns> An object representing the new transaction </returns>
        protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
        {
            if (_fakeConnectionState != null)
            {
                return new EntityTransaction();
            }

            if (CurrentTransaction != null)
            {
                throw new InvalidOperationException(Strings.EntityClient_TransactionAlreadyStarted);
            }

            if (_storeConnection == null)
            {
                throw Error.EntityClient_ConnectionStringNeededBeforeOperation();
            }

            if (State != ConnectionState.Open)
            {
                throw Error.EntityClient_ConnectionNotOpen();
            }

            var interceptionContext = new BeginTransactionInterceptionContext(InterceptionContext);
            if (isolationLevel != IsolationLevel.Unspecified)
            {
                interceptionContext = interceptionContext.WithIsolationLevel(isolationLevel);
            }

            DbTransaction storeTransaction = null;
            try
            {
                var executionStrategy = DbProviderServices.GetExecutionStrategy(_storeConnection, GetMetadataWorkspace());
                storeTransaction = executionStrategy.Execute(
                    () =>
                    {
                        if (DbInterception.Dispatch.Connection.GetState(_storeConnection, InterceptionContext) == ConnectionState.Broken)
                        {
                            DbInterception.Dispatch.Connection.Close(_storeConnection, interceptionContext);
                        }

                        if (DbInterception.Dispatch.Connection.GetState(_storeConnection, InterceptionContext) == ConnectionState.Closed)
                        {
                            DbInterception.Dispatch.Connection.Open(_storeConnection, interceptionContext);
                        }

                        return DbInterception.Dispatch.Connection.BeginTransaction(
                            _storeConnection,
                            interceptionContext);
                    });
            }
            catch (Exception e)
            {
                if (e.IsCatchableExceptionType())
                {
                    throw new EntityException(Strings.EntityClient_ErrorInBeginningTransaction, e);
                }
                throw;
            }

            // The provider is problematic if it succeeded in beginning a transaction but returned a null
            // for the transaction object
            if (storeTransaction == null)
            {
                throw new ProviderIncompatibleException(
                    Strings.EntityClient_ReturnedNullOnProviderMethod("BeginTransaction", _storeConnection.GetType().Name));
            }

            _currentTransaction = new EntityTransaction(this, storeTransaction);
            return _currentTransaction;
        }
示例#36
0
 /// <summary>
 /// 在开启一个数据库事务动作执行前瞬间触发。当开始事务操作时将数据库连接字符串更新至 Master 数据库。
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="interceptionContext"></param>
 public override void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
     this.UpdateConnectionStringIfNeed(connection, this.Config.UsableMasterConnectionString, interceptionContext.DbContexts);
 }
示例#37
0
        private void ExecuteStatementsWithinNewTransaction(
            IEnumerable<MigrationStatement> migrationStatements, DbConnection connection,
            DbInterceptionContext interceptionContext)
        {
            DebugCheck.NotNull(migrationStatements);
            DebugCheck.NotNull(connection);

            var beginTransactionInterceptionContext
                = new BeginTransactionInterceptionContext(interceptionContext)
                    .WithIsolationLevel(IsolationLevel.Serializable);

            DbTransaction transaction = null;
            try
            {
                transaction
                    = DbInterception.Dispatch.Connection.BeginTransaction(
                        connection, beginTransactionInterceptionContext);

                ExecuteStatementsWithinTransaction(migrationStatements, transaction, interceptionContext);

                DbInterception.Dispatch.Transaction.Commit(transaction, interceptionContext);
            }
            finally
            {
                if (transaction != null)
                {
                    DbInterception.Dispatch.Transaction.Dispose(transaction, interceptionContext);
                }
            }
        }
 public void BeganTransaction_logs_exceptions()
 {
     var writer = new StringWriter();
     var interceptionContext = new BeginTransactionInterceptionContext();
     interceptionContext.Exception = new Exception("Boo");
     new DatabaseLogFormatter(writer.Write).BeganTransaction(new Mock<DbConnection>().Object, interceptionContext);
     Assert.True(
         _resourceVerifier.IsMatch("TransactionStartErrorLog", GetSingleLine(writer), new AnyValueParameter(), "Boo", ""));
 }
 public void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
 {
 }
示例#40
0
        private void ExecuteStatementsInternal(IEnumerable <MigrationStatement> migrationStatements, DbConnection connection)
        {
            DebugCheck.NotNull(migrationStatements);
            DebugCheck.NotNull(connection);

            var context = _contextForInterception ?? _usersContextInfo.CreateInstance();

            var interceptionContext = new DbInterceptionContext();

            interceptionContext = interceptionContext.WithDbContext(context);

            DbInterception.Dispatch.Connection.Open(connection, interceptionContext);

            TransactionHandler transactionHandler = null;

            try
            {
                if (!(context is TransactionContext))
                {
                    var providerInvariantName =
                        DbConfiguration.DependencyResolver.GetService <IProviderInvariantName>(
                            DbProviderServices.GetProviderFactory(connection))
                        .Name;

                    var dataSource = DbInterception.Dispatch.Connection.GetDataSource(connection, interceptionContext);

                    var transactionHandlerFactory = DbConfiguration.DependencyResolver.GetService <Func <TransactionHandler> >(
                        new StoreKey(providerInvariantName, dataSource));

                    if (transactionHandlerFactory != null)
                    {
                        transactionHandler = transactionHandlerFactory();
                        transactionHandler.Initialize(context, connection);
                    }
                }

                var beginTransactionInterceptionContext = new BeginTransactionInterceptionContext(interceptionContext)
                                                          .WithIsolationLevel(IsolationLevel.Serializable);

                using (var transaction = DbInterception.Dispatch.Connection.BeginTransaction(
                           connection,
                           beginTransactionInterceptionContext))
                {
                    foreach (var migrationStatement in migrationStatements)
                    {
                        base.ExecuteSql(transaction, migrationStatement, interceptionContext);
                    }

                    DbInterception.Dispatch.Transaction.Commit(transaction, interceptionContext);
                }
            }
            finally
            {
                if (transactionHandler != null)
                {
                    transactionHandler.Dispose();
                }

                if (_contextForInterception == null)
                {
                    context.Dispose();
                }
            }
        }