I have a command-line utility written in C#, which updates some records in the database and then enters a loop checking some other stuff. For some reason, the SQL execution always leaves a sleeping awaiting command session in SQL server 2008 after SQL execution. I can use SQL server activity monitor and run sp_who2 to confirm that. But SQL transaction has been committed successfully indeed. I can tell this from debugging in the code and the timestamp of the data record in the database. Also, the open sleeping session will be killed when I explicitly stop the command-line utility. This indicates that my function creates some SQL connection object that can’t be disposed of until it is garbage collected by CLR when the application is aborted. How could this happen? Thanks. Here is the code:
bool result = false;
using (SqlConnection conn = new SqlConnection(this.Connection))
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText =
@"if not exists (select id from pl where sj=@sj and ej=@ej and dateInactivated is null)
insert into pl(sj,ej,pf, br, tk, lastModified )
values(@sj,@ej,@pf,@br,@tk,getDate())
else
update pl set sj=@sj,ej=@ej,pf=@pf,br=@br,tk=@tk,lastModified=getDate()
where sj=@sj and ej=@ej and dateInactivated is null
";
cmd.Parameters.AddWithValue("@sj", sj);
cmd.Parameters.AddWithValue("@ej", ej);
cmd.Parameters.AddWithValue("@pf", pf);
cmd.Parameters.AddWithValue("@br", br);
cmd.Parameters.AddWithValue("@tk", tkData);
cmd.CommandTimeout = 60;
SqlTransaction trans = null;
try
{
conn.Open();
trans = conn.BeginTransaction();
cmd.Transaction = trans;
cmd.ExecuteNonQuery();
trans.Commit();
conn.Close();
result = true;
}
catch (SqlException ex)
{
if (trans != null)
{
trans.Rollback();
}
Log.WriteLog(LogLevel.ERROR, ex.Message);
result = false;
}
finally
{
if (conn.State != ConnectionState.Closed)
{
conn.Close();
}
}
}
}
return result;
Note that tk field is an xml database field.
This is called connection pooling, and you want it to work this way.
Basically, dropping a connection entirely and then re-establishing it for your app incurs a much higher penalty than just re-using an idle connection that was left behind from a previous invocation of your code. This is a good thing.
It's due to pooling. 99.99% of the time, this is a great thing - it makes for fewer connections being made and torn down, and if multi-threaded makes for fewer connections being open simultaneously.
If you add Pooling=false to the connection string, it won't be used. About the only reasons for doing this are:
The second is very rare. The first should be very rare - again, emphasis on the temporary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With