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 EnlistTransactionInterceptionContext(); interceptionContext.SuppressExecution(); interceptionContext.Exception = new Exception("Cheez Whiz"); var transaction = new CommittableTransaction(); interceptionContext = interceptionContext .WithDbContext(dbContext) .WithObjectContext(objectContext) .WithTransaction(transaction) .AsAsync(); Assert.Equal(new[] { objectContext }, interceptionContext.ObjectContexts); Assert.Equal(new[] { dbContext }, interceptionContext.DbContexts); Assert.True(interceptionContext.IsAsync); Assert.Same(transaction, interceptionContext.Transaction); Assert.Null(interceptionContext.Exception); Assert.Null(interceptionContext.OriginalException); Assert.False(interceptionContext.IsExecutionSuppressed); }
/// <summary> /// Creates a new <see cref="T:System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext" /> that contains all the contextual information in this /// interception context together with the given <see cref="P:System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext.Transaction" />. /// </summary> /// <param name="transaction">The transaction to be used in the <see cref="M:System.Data.Common.DbConnection.EnlistTransaction(System.Transactions.Transaction)" /> invocation.</param> /// <returns>A new interception context associated with the given isolation level.</returns> public EnlistTransactionInterceptionContext WithTransaction( Transaction transaction) { EnlistTransactionInterceptionContext interceptionContext = this.TypedClone(); interceptionContext._transaction = transaction; return(interceptionContext); }
/// <summary> /// Sends <see cref="M:System.Data.Entity.Infrastructure.Interception.IDbConnectionInterceptor.EnlistingTransaction(System.Data.Common.DbConnection,System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext)" /> and /// <see cref="M:System.Data.Entity.Infrastructure.Interception.IDbConnectionInterceptor.EnlistedTransaction(System.Data.Common.DbConnection,System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext)" /> to any <see cref="T:System.Data.Entity.Infrastructure.Interception.IDbConnectionInterceptor" /> /// registered on <see cref="T:System.Data.Entity.Infrastructure.Interception.DbInterception" /> before/after making a /// call to <see cref="M:System.Data.Common.DbConnection.EnlistTransaction(System.Transactions.Transaction)" />. /// </summary> /// <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> public virtual void EnlistTransaction( DbConnection connection, EnlistTransactionInterceptionContext interceptionContext) { Check.NotNull <DbConnection>(connection, nameof(connection)); Check.NotNull <EnlistTransactionInterceptionContext>(interceptionContext, nameof(interceptionContext)); this.InternalDispatcher.Dispatch <DbConnection, EnlistTransactionInterceptionContext>(connection, (Action <DbConnection, EnlistTransactionInterceptionContext>)((t, c) => t.EnlistTransaction(c.Transaction)), new EnlistTransactionInterceptionContext((DbInterceptionContext)interceptionContext), (Action <IDbConnectionInterceptor, DbConnection, EnlistTransactionInterceptionContext>)((i, t, c) => i.EnlistingTransaction(t, c)), (Action <IDbConnectionInterceptor, DbConnection, EnlistTransactionInterceptionContext>)((i, t, c) => i.EnlistedTransaction(t, c))); }
/// <summary> /// Sends <see cref="IDbConnectionInterceptor.EnlistingTransaction" /> and /// <see cref="IDbConnectionInterceptor.EnlistedTransaction" /> to any <see cref="IDbConnectionInterceptor" /> /// registered on <see cref="DbInterception" /> before/after making a /// call to <see cref="DbConnection.EnlistTransaction" />. /// </summary> /// <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> public virtual void EnlistTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext) { Check.NotNull(connection, "connection"); Check.NotNull(interceptionContext, "interceptionContext"); InternalDispatcher.Dispatch( connection, (t, c) => t.EnlistTransaction(c.Transaction), new EnlistTransactionInterceptionContext(interceptionContext), (i, t, c) => i.EnlistingTransaction(t, c), (i, t, c) => i.EnlistedTransaction(t, c)); }
/// <summary> /// Creates a new <see cref="T:System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext" /> by copying immutable state from the given /// interception context. Also see <see cref="M:System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext.Clone" /> /// </summary> /// <param name="copyFrom">The context from which to copy state.</param> public EnlistTransactionInterceptionContext(DbInterceptionContext copyFrom) : base(copyFrom) { Check.NotNull <DbInterceptionContext>(copyFrom, nameof(copyFrom)); EnlistTransactionInterceptionContext interceptionContext = copyFrom as EnlistTransactionInterceptionContext; if (interceptionContext == null) { return; } this._transaction = interceptionContext._transaction; }
/// <summary> /// Sends <see cref="IDbConnectionInterceptor.EnlistingTransaction" /> and /// <see cref="IDbConnectionInterceptor.EnlistedTransaction" /> to any <see cref="IDbConnectionInterceptor" /> /// registered on <see cref="DbInterception" /> before/after making a /// call to <see cref="DbConnection.EnlistTransaction" />. /// </summary> /// <param name="dbConnection">The connection on which the operation will be executed.</param> /// <param name="interceptionContext">Optional information about the context of the call being made.</param> public virtual void EnlistTransaction(DbConnection dbConnection, EnlistTransactionInterceptionContext interceptionContext) { Check.NotNull(dbConnection, "dbConnection"); Check.NotNull(interceptionContext, "interceptionContext"); var clonedInterceptionContext = new EnlistTransactionInterceptionContext(interceptionContext); InternalDispatcher.Dispatch( () => dbConnection.EnlistTransaction(clonedInterceptionContext.Transaction), clonedInterceptionContext, i => i.EnlistingTransaction(dbConnection, clonedInterceptionContext), i => i.EnlistedTransaction(dbConnection, clonedInterceptionContext)); }
public void Initially_has_no_state() { var interceptionContext = new EnlistTransactionInterceptionContext(); Assert.Empty(interceptionContext.DbContexts); Assert.Null(interceptionContext.Exception); Assert.False(interceptionContext.IsAsync); Assert.False(interceptionContext.IsExecutionSuppressed); Assert.Null(interceptionContext.Transaction); Assert.Empty(interceptionContext.ObjectContexts); Assert.Null(interceptionContext.OriginalException); Assert.Equal((TaskStatus)0, interceptionContext.TaskStatus); }
public void EnlistTransaction_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 transaction = new CommittableTransaction(); var interceptionContext = new EnlistTransactionInterceptionContext().WithTransaction(transaction); dispatcher.EnlistTransaction(mockConnection.Object, interceptionContext); mockConnection.Verify(m => m.EnlistTransaction(transaction), Times.Once()); mockInterceptor.Verify(m => m.EnlistingTransaction(mockConnection.Object, It.IsAny<EnlistTransactionInterceptionContext>()), Times.Once()); mockInterceptor.Verify(m => m.EnlistedTransaction(mockConnection.Object, It.IsAny<EnlistTransactionInterceptionContext>()), Times.Once()); }
public void EnlistTransaction_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 transaction = new CommittableTransaction(); var interceptionContext = new EnlistTransactionInterceptionContext().WithTransaction(transaction); dispatcher.EnlistTransaction(mockConnection.Object, interceptionContext); mockConnection.Verify(m => m.EnlistTransaction(transaction), Times.Once()); mockInterceptor.Verify(m => m.EnlistingTransaction(mockConnection.Object, It.IsAny <EnlistTransactionInterceptionContext>()), Times.Once()); mockInterceptor.Verify(m => m.EnlistedTransaction(mockConnection.Object, It.IsAny <EnlistTransactionInterceptionContext>()), Times.Once()); }
public void EnlistedTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext) { }
/// <summary> /// Enlists this <see cref="T:System.Data.Entity.Core.EntityClient.EntityConnection" /> in the specified transaction. /// </summary> /// <param name="transaction">The transaction object to enlist into.</param> /// <exception cref="T:System.InvalidOperationException"> /// The state of the <see cref="T:System.Data.Entity.Core.EntityClient.EntityConnection" /> is not /// <see /// cref="F:System.Data.ConnectionState.Open" /> /// . /// </exception> public override void EnlistTransaction(Transaction transaction) { if (_storeConnection == null) { throw Error.EntityClient_ConnectionStringNeededBeforeOperation(); } if (State != ConnectionState.Open) { throw Error.EntityClient_ConnectionNotOpen(); } try { var interceptionContext = new EnlistTransactionInterceptionContext(InterceptionContext); interceptionContext = interceptionContext.WithTransaction(transaction); DbInterception.Dispatch.Connection.EnlistTransaction(_storeConnection, interceptionContext); // null means "Unenlist transaction". It is fine if no transaction is in progress (no op). Otherwise // _storeConnection.EnlistTransaction should throw and we would not get here. Debug.Assert( transaction != null || !EnlistedInUserTransaction, "DbConnection should not allow unenlist from a transaction that has not completed."); // It is OK to enlist in null transaction or multiple times in the same transaction. // In the latter case we don't need to be called multiple times when the transaction completes // so subscribe only when enlisting for the first time. Note that _storeConnection.EnlistTransaction // will throw in invalid cases (like enlisting the connection in a transaction when another // transaction has not completed) so when we get here we are sure that either no transactions are // active or the transaction the caller tries enlisting to // is the active transaction. if (transaction != null && !EnlistedInUserTransaction) { transaction.TransactionCompleted += EnlistedTransactionCompleted; } _enlistedTransaction = transaction; } catch (Exception e) { if (e.IsCatchableExceptionType()) { throw new EntityException(Strings.EntityClient_ProviderSpecificError(@"EnlistTransaction"), e); } throw; } }
/// <summary> /// Does not write to log unless overridden. /// </summary> /// <param name="connection">The connection.</param> /// <param name="interceptionContext">Contextual information associated with the call.</param> public virtual void EnlistedTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext) { }
/// <summary> /// 在数据库操作事务提交动作执行前瞬间触发。 /// </summary> /// <param name="connection"></param> /// <param name="interceptionContext"></param> public virtual void EnlistingTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext) { }
public abstract void EnlistingTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext);
public abstract void EnlistedTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext);