/// <summary> /// Constructs the DbContextTransaction object with the associated connection object /// and with the given isolation level /// </summary> /// <param name="connection">The EntityConnection object owning this transaction </param> /// <param name="isolationLevel">The database isolation level with which the underlying store transaction will be created</param> internal DbContextTransaction(EntityConnection connection, IsolationLevel isolationLevel) { DebugCheck.NotNull(connection); _connection = connection; EnsureOpenConnection(); _entityTransaction = _connection.BeginTransaction(isolationLevel); }
public void ExecutionStrategy_is_used_to_recover_from_a_transient_error() { var storeConnectionState = ConnectionState.Open; var transientExceptionThrown = false; var storeConnectionMock = new Mock<DbConnection>(MockBehavior.Strict); storeConnectionMock.Setup(m => m.Close()).Callback(() => storeConnectionState = ConnectionState.Closed); storeConnectionMock.Setup(m => m.Open()).Callback(() => storeConnectionState = ConnectionState.Open); storeConnectionMock.SetupGet(m => m.DataSource).Returns("fake"); storeConnectionMock.SetupGet(m => m.State).Returns(() => storeConnectionState); storeConnectionMock.Protected().Setup<DbTransaction>("BeginDbTransaction", IsolationLevel.Unspecified) .Returns<IsolationLevel>( il => { if (!transientExceptionThrown) { transientExceptionThrown = true; storeConnectionState = ConnectionState.Broken; throw new TimeoutException(); } return new Mock<DbTransaction>().Object; }); var entityConnection = new EntityConnection(CreateMetadataWorkspaceMock().Object, storeConnectionMock.Object, true, true); var executionStrategyMock = new Mock<IDbExecutionStrategy>(); executionStrategyMock.Setup(m => m.Execute(It.IsAny<Func<DbTransaction>>())).Returns<Func<DbTransaction>>( a => { storeConnectionMock.Protected() .Verify<DbTransaction>( "BeginDbTransaction", Times.Never(), IsolationLevel.Unspecified); Assert.Throws<TimeoutException>(() => a()); storeConnectionMock.Protected() .Verify<DbTransaction>( "BeginDbTransaction", Times.Once(), IsolationLevel.Unspecified); var result = a(); storeConnectionMock.Protected() .Verify<DbTransaction>( "BeginDbTransaction", Times.Exactly(2), IsolationLevel.Unspecified); return result; }); MutableResolver.AddResolver<Func<IDbExecutionStrategy>>(key => (Func<IDbExecutionStrategy>)(() => executionStrategyMock.Object)); try { entityConnection.BeginTransaction(); } finally { MutableResolver.ClearResolvers(); } executionStrategyMock.Verify(m => m.Execute(It.IsAny<Func<DbTransaction>>()), Times.Once()); }
public void Should_use_interception() { var mockConnection = new Mock<DbConnection>(); mockConnection.SetupGet(m => m.DataSource).Returns("Foo"); mockConnection.SetupGet(m => m.State).Returns(ConnectionState.Open); var mockStoreItemCollection = new Mock<StoreItemCollection>(); mockStoreItemCollection .SetupGet(m => m.ProviderFactory) .Returns(DbProviderServices.GetProviderFactory(new SqlConnection())); var mockMetadataWorkspace = new Mock<MetadataWorkspace>(); mockMetadataWorkspace .Setup(m => m.GetItemCollection(DataSpace.SSpace)) .Returns(mockStoreItemCollection.Object); var objectContext = new ObjectContext(); var mockTransaction = new Mock<DbTransaction>(); var mockConnectionInterceptor = new Mock<IDbConnectionInterceptor>(); mockConnectionInterceptor .Setup(m => m.BeginningTransaction(mockConnection.Object, It.IsAny<BeginTransactionInterceptionContext>())) .Callback<DbConnection, BeginTransactionInterceptionContext>( (_, c) => { Assert.Equal(new[] { objectContext }, c.ObjectContexts); Assert.Equal(IsolationLevel.Chaos, c.IsolationLevel); }); mockConnectionInterceptor .Setup(m => m.BeganTransaction(mockConnection.Object, It.IsAny<BeginTransactionInterceptionContext>())) .Callback<DbConnection, BeginTransactionInterceptionContext>( (_, c) => { Assert.Equal(new[] { objectContext }, c.ObjectContexts); Assert.Equal(IsolationLevel.Chaos, c.IsolationLevel); Assert.Same(mockTransaction.Object, c.Result); }); mockConnection .Protected() .Setup<DbTransaction>("BeginDbTransaction", ItExpr.IsAny<IsolationLevel>()) .Returns(mockTransaction.Object); EntityConnection connection; DbInterception.Add(mockConnectionInterceptor.Object); try { connection = new EntityConnection( mockMetadataWorkspace.Object, mockConnection.Object, true, true); connection.AssociateContext(objectContext); connection.BeginTransaction(IsolationLevel.Chaos); } finally { DbInterception.Remove(mockConnectionInterceptor.Object); } mockConnectionInterceptor.Verify( m => m.BeginningTransaction(mockConnection.Object, It.IsAny<BeginTransactionInterceptionContext>()), Times.Once()); mockConnectionInterceptor.Verify( m => m.BeganTransaction(mockConnection.Object, It.IsAny<BeginTransactionInterceptionContext>()), Times.Once()); mockConnection .Protected() .Verify<DbTransaction>("BeginDbTransaction", Times.Once(), ItExpr.IsAny<IsolationLevel>()); mockConnectionInterceptor.Verify( m => m.StateGetting(It.IsAny<DbConnection>(), It.IsAny<DbConnectionInterceptionContext<ConnectionState>>()), Times.Exactly(3)); mockConnectionInterceptor.Verify( m => m.StateGot(It.IsAny<DbConnection>(), It.IsAny<DbConnectionInterceptionContext<ConnectionState>>()), Times.Exactly(3)); mockConnection.Verify(m => m.State, Times.Exactly(3)); Assert.Equal(ConnectionState.Open, connection.State); }