An issue has arisen due to a code refactor, what is the best solution in this case?
The issue is that the DbConnection was refactored from a local method variable into a class variable.
The application is multithreaded.
It appeared that the issue is with the DbConnection object being shared when it is a member variable.
What is the best solution? leave it as a local method varaible?
public IDataReader Execute(CommandBehavior behavior, string[] parameterNames, object[] arguments)
{
DbConnection conn = null;
try
{
conn = Connection.CreateConnection();
DbCommand cmd = conn.CreateCommand();
cmd.CommandText = StoredProcedureName;
cmd.CommandType = CommandType.StoredProcedure;
// ..................................................
// Perform the call.
return DataCachingContext.SetCachedData(call, cmd.ExecuteReader(behavior));
}
catch (Exception ex)
{
//..........................
}
finally
{
//
}
}
Just to clarify, here is the version which causes issue. with a runtime exception, issues with indexing into ResultSets, this is most likely due to the connection being overwritten.
DbConnection _conn = null;
public IDataReader Execute(CommandBehavior behavior, string[] parameterNames, object[] arguments)
{
try
{
_conn = Connection.CreateConnection();
DbCommand cmd = _conn.CreateCommand();
cmd.CommandText = StoredProcedureName;
cmd.CommandType = CommandType.StoredProcedure;
// ..................................................
// Perform the call.
return DataCachingContext.SetCachedData(call, cmd.ExecuteReader(behavior));
}
catch (Exception ex)
{
//..........................
}
finally
{
//
}
}
After more investigation it looks like the DbConnection variable was made a class variable to enable unit testing. When it’s a local variable there’s no way to test it’s value. The state of the DbConnection was being tested
Yes, a good pattern for using
DbConnectionis to create and dispose the connection in a method (storing it in local variable). Behind the scenes the connections are pooled so there is no significant overhead in doing it like this. You also avoid having to deal with shared state and locks.The code provided in the question does exactly what I describe here.