Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Inconsistent Connection Pooling Behavior

Inconsistent Connection Pooling Behavior

Scheduled Pinned Locked Moved C#
helpcsharpasp-netdatabase
11 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Jason Pease

    I'm not sure if anyone will be able to help me with this problem without actually debugging the code, but I thought I'd give it a shot. Here's the situation. I have a fairly mature and stable C#/ASP.NET application that I inherited a few years back. I'm familiar with nearly all of the code, but there are few classes here and there that I've never had to deal with; I know they work and that's it. Late last night we came across a bug in which connections were getting leaked until the pool was saturated with the default 100 connections. It turned out that the connections were getting orphaned in a class that hasn't been touched in about five years. As strange as that is, the part that I really can't explain is that the method is called an several places in the application and it works correctly. However, when it is called in a page that was recently added to the application it leaks connections like a siv. If it can help, here's the offending method (underscores added for legibility). public int GetUserID(String UserName) { ________// Create Instance of Connection and Command Object ________SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["connectionStringUSR"]); ________SqlCommand myCommand = new SqlCommand("GetSingleUserID", myConnection); ________// Mark the Command as a SPROC ________myCommand.CommandType = CommandType.StoredProcedure; ________// Add Parameters to SPROC ________SqlParameter parameterEmail = new SqlParameter("@Email", SqlDbType.NVarChar, 100); ________parameterEmail.Value = UserName; ________myCommand.Parameters.Add(parameterEmail); ________if ((parameterEmail.Value != null) && (parameterEmail.Value != System.DBNull.Value)) ________{ ________________// Open the database connection and execute the command ________________myConnection.Open(); ________________SqlDataReader dr = myCommand.ExecuteReader(CommandBehavior.CloseConnection); ________________if(dr.Read()==true) ________________{ ________________________if(dr.IsDBNull(0)) ________________________________return -1; ________________________else ________________________________return dr.GetInt32(0); ________________} ________________else ________________{ ________________________return -1; ________________} ________} ________else ________{ ________________return -1; ________} } The myConnection.Close() is missing, but the CommandBehavior is set to CloseConnection so it should be getting closed c

    A Offline
    A Offline
    althamda
    wrote on last edited by
    #2

    I don't know about you but I don't really trust something to close my connections for me. I'd have the open in a try block and the close in a finally block.

    J 1 Reply Last reply
    0
    • A althamda

      I don't know about you but I don't really trust something to close my connections for me. I'd have the open in a try block and the close in a finally block.

      J Offline
      J Offline
      Jason Pease
      wrote on last edited by
      #3

      I couldn't agree more, in fact that's precisely what I did to correct the problem. But I also need to explain why the previous code behaved as it did, both for formal justifications as well as my own curiosity.

      A 1 Reply Last reply
      0
      • J Jason Pease

        I couldn't agree more, in fact that's precisely what I did to correct the problem. But I also need to explain why the previous code behaved as it did, both for formal justifications as well as my own curiosity.

        A Offline
        A Offline
        althamda
        wrote on last edited by
        #4

        I'd say that a connection that is opened must always be closed, no exceptions. It's plain bad coding to rely on something else to auto close a connection. As for why the code behaved as it did - I'd just put it down to badly written code.

        1 Reply Last reply
        0
        • J Jason Pease

          I'm not sure if anyone will be able to help me with this problem without actually debugging the code, but I thought I'd give it a shot. Here's the situation. I have a fairly mature and stable C#/ASP.NET application that I inherited a few years back. I'm familiar with nearly all of the code, but there are few classes here and there that I've never had to deal with; I know they work and that's it. Late last night we came across a bug in which connections were getting leaked until the pool was saturated with the default 100 connections. It turned out that the connections were getting orphaned in a class that hasn't been touched in about five years. As strange as that is, the part that I really can't explain is that the method is called an several places in the application and it works correctly. However, when it is called in a page that was recently added to the application it leaks connections like a siv. If it can help, here's the offending method (underscores added for legibility). public int GetUserID(String UserName) { ________// Create Instance of Connection and Command Object ________SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["connectionStringUSR"]); ________SqlCommand myCommand = new SqlCommand("GetSingleUserID", myConnection); ________// Mark the Command as a SPROC ________myCommand.CommandType = CommandType.StoredProcedure; ________// Add Parameters to SPROC ________SqlParameter parameterEmail = new SqlParameter("@Email", SqlDbType.NVarChar, 100); ________parameterEmail.Value = UserName; ________myCommand.Parameters.Add(parameterEmail); ________if ((parameterEmail.Value != null) && (parameterEmail.Value != System.DBNull.Value)) ________{ ________________// Open the database connection and execute the command ________________myConnection.Open(); ________________SqlDataReader dr = myCommand.ExecuteReader(CommandBehavior.CloseConnection); ________________if(dr.Read()==true) ________________{ ________________________if(dr.IsDBNull(0)) ________________________________return -1; ________________________else ________________________________return dr.GetInt32(0); ________________} ________________else ________________{ ________________________return -1; ________________} ________} ________else ________{ ________________return -1; ________} } The myConnection.Close() is missing, but the CommandBehavior is set to CloseConnection so it should be getting closed c

          G Offline
          G Offline
          Guffa
          wrote on last edited by
          #5

          Of course the behaviour depends on what else is happening in the code. You are never closing the data reader, so it will be depending on garbage collections to finalize it. If there doesn't happen to be a garbage collection soon, it will be leaking the connection.

          Jason Pease wrote:

          it leaks connections like a siv

          Perhaps even like a sieve? ;)

          Jason Pease wrote:

          nderscores added for legibility

          So much work for something that didn't end up very good anyway... Use the pre tag instead.

          --- It's amazing to see how much work some people will go through just to avoid a little bit of work.

          J 1 Reply Last reply
          0
          • G Guffa

            Of course the behaviour depends on what else is happening in the code. You are never closing the data reader, so it will be depending on garbage collections to finalize it. If there doesn't happen to be a garbage collection soon, it will be leaking the connection.

            Jason Pease wrote:

            it leaks connections like a siv

            Perhaps even like a sieve? ;)

            Jason Pease wrote:

            nderscores added for legibility

            So much work for something that didn't end up very good anyway... Use the pre tag instead.

            --- It's amazing to see how much work some people will go through just to avoid a little bit of work.

            J Offline
            J Offline
            Jason Pease
            wrote on last edited by
            #6

            Guffa wrote:

            Of course the behaviour depends on what else is happening in the code. You are never closing the data reader, so it will be depending on garbage collections to finalize it. If there doesn't happen to be a garbage collection soon, it will be leaking the connection.

            The garbage collection doesn't seems to be the issue based on the counters in perfmon, but I'm not sure how reliable they are.

            Guffa wrote:

            Perhaps even like a sieve?

            No, more like a siv. Very very leaky.

            Guffa wrote:

            So much work for something that didn't end up very good anyway... Use the pre tag instead.

            Nice tip. Can you tell I don't post that often? Thanks, Jason

            G 1 Reply Last reply
            0
            • J Jason Pease

              Guffa wrote:

              Of course the behaviour depends on what else is happening in the code. You are never closing the data reader, so it will be depending on garbage collections to finalize it. If there doesn't happen to be a garbage collection soon, it will be leaking the connection.

              The garbage collection doesn't seems to be the issue based on the counters in perfmon, but I'm not sure how reliable they are.

              Guffa wrote:

              Perhaps even like a sieve?

              No, more like a siv. Very very leaky.

              Guffa wrote:

              So much work for something that didn't end up very good anyway... Use the pre tag instead.

              Nice tip. Can you tell I don't post that often? Thanks, Jason

              G Offline
              G Offline
              Guffa
              wrote on last edited by
              #7

              Jason Pease wrote:

              The garbage collection doesn't seems to be the issue based on the counters in perfmon, but I'm not sure how reliable they are.

              You are missing the point. Read my reply again, and see if you can spot where I say that you are never closing the data reader.

              --- It's amazing to see how much work some people will go through just to avoid a little bit of work.

              J 1 Reply Last reply
              0
              • G Guffa

                Jason Pease wrote:

                The garbage collection doesn't seems to be the issue based on the counters in perfmon, but I'm not sure how reliable they are.

                You are missing the point. Read my reply again, and see if you can spot where I say that you are never closing the data reader.

                --- It's amazing to see how much work some people will go through just to avoid a little bit of work.

                J Offline
                J Offline
                Jason Pease
                wrote on last edited by
                #8

                Perhaps, you are missing the point. Try to read my initial post again and see you if you can pick out the phrase where I say the code works, and has worked for years, correctly in many parts of the application. If it were simply a question of never closing the data reader it would have leaked connections from day one. Or am I missing something here? --- It's amazing how rude some people are to people that they don't know

                A G 2 Replies Last reply
                0
                • J Jason Pease

                  Perhaps, you are missing the point. Try to read my initial post again and see you if you can pick out the phrase where I say the code works, and has worked for years, correctly in many parts of the application. If it were simply a question of never closing the data reader it would have leaked connections from day one. Or am I missing something here? --- It's amazing how rude some people are to people that they don't know

                  A Offline
                  A Offline
                  althamda
                  wrote on last edited by
                  #9

                  It could depend on a lot of things as to why connections haven't been leaking up until recently. But it still stands that the connection and the data reader both need closing. I wouldn't bother looking into this too far as you never wrote the code, just fix it and move on.

                  1 Reply Last reply
                  0
                  • J Jason Pease

                    Perhaps, you are missing the point. Try to read my initial post again and see you if you can pick out the phrase where I say the code works, and has worked for years, correctly in many parts of the application. If it were simply a question of never closing the data reader it would have leaked connections from day one. Or am I missing something here? --- It's amazing how rude some people are to people that they don't know

                    G Offline
                    G Offline
                    Guffa
                    wrote on last edited by
                    #10

                    Jason Pease wrote:

                    Perhaps, you are missing the point.

                    Nope. :)

                    Jason Pease wrote:

                    Try to read my initial post again and see you if you can pick out the phrase where I say the code works, and has worked for years, correctly in many parts of the application.

                    I saw that when I read it the first time. The fact the code does not produce errors is in no way any guarantee that it is correct.

                    Jason Pease wrote:

                    If it were simply a question of never closing the data reader it would have leaked connections from day one.

                    It's not simply a question of not closing the data reader. As I explained, it depends on whether there are any garbage collections occuring that will finalize the data reader or not. If the code would have closed the data reader, it would not have to depend on the garbage collector. The code has been incorrect from day one. You have just been lucky that the garbage collector has been picking up the slack.

                    --- It's amazing to see how much work some people will go through just to avoid a little bit of work.

                    1 Reply Last reply
                    0
                    • J Jason Pease

                      I'm not sure if anyone will be able to help me with this problem without actually debugging the code, but I thought I'd give it a shot. Here's the situation. I have a fairly mature and stable C#/ASP.NET application that I inherited a few years back. I'm familiar with nearly all of the code, but there are few classes here and there that I've never had to deal with; I know they work and that's it. Late last night we came across a bug in which connections were getting leaked until the pool was saturated with the default 100 connections. It turned out that the connections were getting orphaned in a class that hasn't been touched in about five years. As strange as that is, the part that I really can't explain is that the method is called an several places in the application and it works correctly. However, when it is called in a page that was recently added to the application it leaks connections like a siv. If it can help, here's the offending method (underscores added for legibility). public int GetUserID(String UserName) { ________// Create Instance of Connection and Command Object ________SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["connectionStringUSR"]); ________SqlCommand myCommand = new SqlCommand("GetSingleUserID", myConnection); ________// Mark the Command as a SPROC ________myCommand.CommandType = CommandType.StoredProcedure; ________// Add Parameters to SPROC ________SqlParameter parameterEmail = new SqlParameter("@Email", SqlDbType.NVarChar, 100); ________parameterEmail.Value = UserName; ________myCommand.Parameters.Add(parameterEmail); ________if ((parameterEmail.Value != null) && (parameterEmail.Value != System.DBNull.Value)) ________{ ________________// Open the database connection and execute the command ________________myConnection.Open(); ________________SqlDataReader dr = myCommand.ExecuteReader(CommandBehavior.CloseConnection); ________________if(dr.Read()==true) ________________{ ________________________if(dr.IsDBNull(0)) ________________________________return -1; ________________________else ________________________________return dr.GetInt32(0); ________________} ________________else ________________{ ________________________return -1; ________________} ________} ________else ________{ ________________return -1; ________} } The myConnection.Close() is missing, but the CommandBehavior is set to CloseConnection so it should be getting closed c

                      P Offline
                      P Offline
                      Pete OHanlon
                      wrote on last edited by
                      #11

                      Jason This is actually quite a subtle one, but the problem is because the connection is closed with CommandBehavior.CloseConnection only when the datareader is closed (which isn't happening in this case). So, you've either got to call dr.Close, or remove the call to CommandBehavior and close the connection explicitly. Hint, try this:

                      using (SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["connectionStringUSR"]))
                      {
                      ... Do the other database work here...
                      }
                      

                      or

                      SqlDataReader dr = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
                      try
                      {
                        if(dr.Read()==true)
                        {
                          if(dr.IsDBNull(0))
                            return -1;
                          else
                            return dr.GetInt32(0);
                        }
                        else
                        {
                          return -1;
                        }
                      }
                      finally
                      {
                        dr.Close();
                      }
                      

                      the last thing I want to see is some pasty-faced geek with skin so pale that it's almost translucent trying to bump parts with a partner - John Simmons / outlaw programmer
                      Deja View - the feeling that you've seen this post before.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups