public override void Dispose() { _connection.Dispose(); if (_deleteDatabase) { DeleteDatabase(Name); } }
protected override void Dispose(bool disposing) { if (_disposed) { return; } if (disposing) { SpannerConnection.Dispose(); } _disposed = true; base.Dispose(disposing); }
public async Task AbortedThrownCorrectly() { // connection 1 starts a transaction and reads // connection 2 starts a transaction and reads the same row // connection 1 writes and commits // connection 2 reads again -- abort should be thrown. // Note: deeply nested using statements to ensure that we dispose of everything even in the case of failure, // but we manually dispose of both tx1 and connection1. using (var connection1 = new SpannerConnection(_fixture.ConnectionString)) { using (var connection2 = new SpannerConnection(_fixture.ConnectionString)) { await Task.WhenAll(connection1.OpenAsync(), connection2.OpenAsync()); using (var tx1 = await connection1.BeginTransactionAsync()) { // TX1 READ using (var cmd = CreateSelectAllCommandForKey(connection1)) { cmd.Transaction = tx1; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.True(await reader.ReadAsync()); } } // TX2 START using (var tx2 = await connection2.BeginTransactionAsync()) { // TX2 READ using (var cmd = CreateSelectAllCommandForKey(connection2)) { cmd.Transaction = tx2; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.True(await reader.ReadAsync()); } } // TX1 WRITE/COMMIT using (var cmd = connection1.CreateUpdateCommand(_fixture.TableName)) { cmd.Parameters.Add("k", SpannerDbType.String, _key); cmd.Parameters.Add("Int64Value", SpannerDbType.Int64, 0); cmd.Transaction = tx1; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); await tx1.CommitAsync().ConfigureAwait(false); tx1.Dispose(); } connection1.Dispose(); // TX2 READ AGAIN/THROWS using (var cmd = CreateSelectAllCommandForKey(connection2)) { cmd.Transaction = tx2; using (var reader = await cmd.ExecuteReaderAsync()) { var thrownException = await Assert.ThrowsAsync <SpannerException>(() => reader.ReadAsync()); Assert.True(thrownException.IsRetryable); } } } } } } }
public async Task AbortedThrownCorrectly() { // connection 1 starts a transaction and reads // connection 2 starts a transaction and reads the same row // connection 1 writes and commits // connection 2 reads again -- abort should be thrown. var connection1 = new SpannerConnection(_fixture.ConnectionString); var connection2 = new SpannerConnection(_fixture.ConnectionString); await Task.WhenAll(connection1.OpenAsync(), connection2.OpenAsync()); var tx1 = await connection1.BeginTransactionAsync(); // TX1 READ using (var cmd = CreateSelectAllCommandForKey(connection1)) { cmd.Transaction = tx1; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.True(await reader.ReadAsync()); } } // TX2 START var tx2 = await connection2.BeginTransactionAsync(); // TX2 READ using (var cmd = CreateSelectAllCommandForKey(connection2)) { cmd.Transaction = tx2; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.True(await reader.ReadAsync()); } } // TX1 WRITE/COMMIT using (var cmd = connection1.CreateUpdateCommand(_fixture.TableName)) { cmd.Parameters.Add("k", SpannerDbType.String, _key); cmd.Parameters.Add("Int64Value", SpannerDbType.Int64, 0); cmd.Transaction = tx1; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); await tx1.CommitAsync().ConfigureAwait(false); tx1.Dispose(); } connection1.Dispose(); // TX2 READ AGAIN/THROWS var thrownException = await Assert.ThrowsAsync <SpannerException>( async() => { using (var cmd = CreateSelectAllCommandForKey(connection2)) { cmd.Transaction = tx2; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.True(await reader.ReadAsync()); } } }).ConfigureAwait(false); tx2.Dispose(); connection2.Dispose(); Assert.True(thrownException?.IsRetryable ?? false); }
public async Task AbortedThrownCorrectly() { await WriteSampleRowsAsync(); // connection 1 starts a transaction and reads // connection 2 starts a transaction and reads the same row // connection 1 writes and commits // connection 2 reads again -- abort should be thrown. var connection1 = new SpannerConnection(_testFixture.ConnectionString); var connection2 = new SpannerConnection(_testFixture.ConnectionString); await Task.WhenAll(connection1.OpenAsync(), connection2.OpenAsync()); var tx1 = await connection1.BeginTransactionAsync(); // TX1 READ using (var cmd = connection1.CreateSelectCommand( "SELECT * FROM TX WHERE K=@k", new SpannerParameterCollection { { "k", _key, SpannerDbType.String } })) { cmd.Transaction = tx1; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.True(await reader.ReadAsync()); } } // TX2 START var tx2 = await connection2.BeginTransactionAsync(); // TX2 READ using (var cmd = connection2.CreateSelectCommand( "SELECT * FROM TX WHERE K=@k", new SpannerParameterCollection { { "k", _key, SpannerDbType.String } })) { cmd.Transaction = tx2; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.True(await reader.ReadAsync()); } } // TX1 WRITE/COMMIT using (var cmd = connection1.CreateUpdateCommand( "TX", new SpannerParameterCollection { { "k", _key, SpannerDbType.String }, { "Int64Value", 0, SpannerDbType.Int64 } })) { cmd.Transaction = tx1; await cmd.ExecuteNonQueryAsync().ConfigureAwait(false); await tx1.CommitAsync().ConfigureAwait(false); tx1.Dispose(); } connection1.Dispose(); // TX2 READ AGAIN/THROWS SpannerException thrownException = null; try { using (var cmd = connection2.CreateSelectCommand( "SELECT * FROM TX WHERE K=@k", new SpannerParameterCollection { { "k", _key, SpannerDbType.String } })) { cmd.Transaction = tx2; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.True(await reader.ReadAsync()); } } } catch (SpannerException ex) { thrownException = ex; } finally { tx2.Dispose(); connection2.Dispose(); } Assert.True(thrownException?.IsRetryable ?? false); }
public override void Dispose() { _connection.Dispose(); base.Dispose(); }