Skip to content

Commit

Permalink
Merge pull request dotnet/corefx#31631 from keeratsingh/gh_30738_SqlC…
Browse files Browse the repository at this point in the history
…onnectionErrorLinux

[Fix] GH 30738 SqlConnection error when executing query after SQL server killed connections(Linux)

Commit migrated from dotnet/corefx@6351e9c
  • Loading branch information
AfsanehR-zz authored Aug 17, 2018
2 parents 01fab33 + dc3fac0 commit f00c55e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,17 @@ public override uint CheckConnection()
{
try
{
if (!_socket.Connected || _socket.Poll(0, SelectMode.SelectError))
// _socket.Poll method with argument SelectMode.SelectRead returns
// True : if Listen has been called and a connection is pending, or
// True : if data is available for reading, or
// True : if the connection has been closed, reset, or terminated, i.e no active connection.
// False : otherwise.
// _socket.Available property returns the number of bytes of data available to read.
//
// Since _socket.Connected alone doesn't guarantee if the connection is still active, we use it in
// combination with _socket.Poll method and _socket.Available == 0 check. When both of them
// return true we can safely determine that the connection is no longer active.
if (!_socket.Connected || (_socket.Poll(100, SelectMode.SelectRead) && _socket.Available == 0))
{
return TdsEnums.SNI_ERROR;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,11 @@ public static string GenerateTableName()
public static void RunNonQuery(string connectionString, string sql)
{
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = connection.CreateCommand())
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = sql;
command.ExecuteNonQuery();
}
command.CommandText = sql;
command.ExecuteNonQuery();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ public static class ConnectivityParametersTest
{
private const string COL_PROGRAM_NAME = "ProgramName";
private const string COL_HOSTNAME = "HostName";
private static readonly string s_databaseName = "d_" + Guid.NewGuid().ToString().Replace('-', '_');
private static readonly string s_tableName = "Person";
private static readonly string s_connectionString = DataTestUtility.TcpConnStr;
private static readonly string s_dbConnectionString = new SqlConnectionStringBuilder(s_connectionString) { InitialCatalog = s_databaseName }.ConnectionString;
private static readonly string s_createDatabaseCmd = $"CREATE DATABASE {s_databaseName}";
private static readonly string s_createTableCmd = $"CREATE TABLE {s_tableName} (NAME NVARCHAR(40), AGE INT)";
private static readonly string s_alterDatabaseSingleCmd = $"ALTER DATABASE {s_databaseName} SET SINGLE_USER WITH ROLLBACK IMMEDIATE;";
private static readonly string s_alterDatabaseMultiCmd = $"ALTER DATABASE {s_databaseName} SET MULTI_USER WITH ROLLBACK IMMEDIATE;";
private static readonly string s_selectTableCmd = $"SELECT COUNT(*) FROM {s_tableName}";
private static readonly string s_dropDatabaseCmd = $"DROP DATABASE {s_databaseName}";

[CheckConnStrSetupFact]
public static void EnvironmentHostNameTest()
Expand Down Expand Up @@ -169,5 +179,35 @@ public void SqlConnectionOpen()
_doneEvent.Set();
}
}

[CheckConnStrSetupFact]
public static void ConnectionKilledTest()
{
try
{
// Setup Database and Table.
DataTestUtility.RunNonQuery(s_connectionString, s_createDatabaseCmd);
DataTestUtility.RunNonQuery(s_dbConnectionString, s_createTableCmd);

// Kill all the connections and set Database to SINGLE_USER Mode.
DataTestUtility.RunNonQuery(s_connectionString, s_alterDatabaseSingleCmd);
// Set Database back to MULTI_USER Mode
DataTestUtility.RunNonQuery(s_connectionString, s_alterDatabaseMultiCmd);

// Execute SELECT statement.
DataTestUtility.RunNonQuery(s_dbConnectionString, s_selectTableCmd);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
Assert.Null(ex);
}
finally
{
// Kill all the connections, set Database to SINGLE_USER Mode and drop Database
DataTestUtility.RunNonQuery(s_connectionString, s_alterDatabaseSingleCmd);
DataTestUtility.RunNonQuery(s_connectionString, s_dropDatabaseCmd);
}
}
}
}

0 comments on commit f00c55e

Please sign in to comment.