1

I have some problems in database connection and wonder if I have something wrong in my code. Please review. This question is related: Switch between databases, use two databases simultaneously question.

cs="Data Source=mywebsite.com;Initial Catalog=database;User Id=root;Password=toor;Connect Timeout=10;Pooling='true';"

using (SqlConnection cnn = new SqlConnection(WebConfigurationManager.ConnectionStrings["cs"].ConnectionString))
{
    using (SqlCommand cmmnd = new SqlCommand("", cnn))
    {
        try
        {
            cnn.Open();

            #region Header & Description
            cmmnd.Parameters.Add("@CatID", SqlDbType.Int).Value = catId;
            cmmnd.CommandText = "SELECT UpperID, Title, Description FROM Categories WHERE CatID=@CatID;";

            string mainCat = String.Empty, rootCat = String.Empty;

            using (SqlDataReader rdr = cmmnd.ExecuteReader())
            {
                if (rdr.Read())
                {
                    mainCat = rdr["Title"].ToString();
                    upperId = Convert.ToInt32(rdr["UpperID"]);
                    description = rdr["Title"];
                }
                else { Response.Redirect("/", false); }
            }

            if (upperId > 0) //If upper category exists add its name
            {
                cmmnd.Parameters["@CatID"].Value = upperId;
                cmmnd.CommandText = "SELECT Title FROM Categories WHERE CatID=@CatID;";
                using (SqlDataReader rdr = cmmnd.ExecuteReader())
                {
                    if (rdr.Read())
                    {
                        rootCat = "<a href='x.aspx'>" + rdr["Title"] + "</a> &raquo; ";
                    }
                }
            }
            #endregion

            #region Sub-Categories
            if (upperId == 0) //show only at root categories
            {
                cmmnd.Parameters["@CatID"].Value = catId;
                cmmnd.CommandText = "SELECT Count(CatID) FROM Categories WHERE UpperID=@CatID;";

                if (Convert.ToInt32(cmmnd.ExecuteScalar()) > 0)
                {
                    cmmnd.CommandText = "SELECT CatID, Title FROM Categories WHERE UpperID=@CatID ORDER BY Title;";

                    using (SqlDataReader rdr = cmmnd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            subcat.InnerHtml += "<a href='x.aspx'>" + rdr["Title"].ToString().ToLower() + "</a>\n";
                            description += rdr["Title"] + ", ";
                        }
                    }
                }
            }
            #endregion
        }
        catch (Exception ex) { HasanG.LogException(ex, Request.RawUrl, HttpContext.Current); Response.Redirect("/", false); }
        finally { cnn.Close(); }
    }
}

The random errors I'm receiving are:

  • A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)
  • A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
  • Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
  • Cannot open database "db" requested by the login. The login failed. Login failed for user 'root'.
Community
  • 1
  • 1
HasanG
  • 12,734
  • 29
  • 100
  • 154
  • Is the code right and do I have mistakes? – HasanG Dec 28 '10 at 23:03
  • What happens when you try to run it? We can't test it for you. Also, why do you say this has something to do with the two-database problem? There's only one database here. – egrunin Dec 28 '10 at 23:05
  • I dont say I have tho database problem. I have one database with which I'm having connection problems. Chris Lively said I could have mistakes in my code and asked me to write it here. http://stackoverflow.com/questions/4547070/switch-between-databases-use-two-databases-simultaneously/4547460#4547460 – HasanG Dec 28 '10 at 23:11
  • @egrunin: This is a carry over question from another one of his. The problem is that his database server is flaking out with everything from connection pool overflows to inability to connect to sql server. I wanted to see his code, but it was going a bit out of scope of the previous question. – NotMe Dec 28 '10 at 23:31

4 Answers4

3

There's no real issues here.

You don't need the extraneous finally { cnn.close(); } as the using clause will take care of that for you. However changing it will have exactly zero impact.

Another thing is that I would put the try .. catch outside of the using clause with a redirect. But, again, I don't think that would affect the dispose from being called.

It's interesting that you would get connection pool errors (timeout expired) if you are always properly disposing of your connections, as you've shown.

Which leaves us with only one real solution: switch hosting providers. They have either overloaded their DB server to the point of unusability or some hardware element in their network setup (nic, switch, router, etc) is bad and dropping packets.

NotMe
  • 87,343
  • 27
  • 171
  • 245
  • Okay, you're right and I agree with you. Using two databases seemed good solution for me. But it would be very complex that way. – HasanG Dec 28 '10 at 23:52
1

If you're connecting remotely to a database provider, you need to look at several possibilities like your own network configuration, firewall setup, etc.

Use a packet sniffer to figure out if lost packets are the issue.

Connection pooling is setup on your local machine, the server making the connections. If the database provider only allows for 5 connections and your connection pool is setup for 50 connections, well... you can do the math. It looks like you're closing the connections properly, so no issues there.

True... one error on "description = rdr["Title"];", should that be "description = rdr["Description"].ToString()"?

No need to put a using statement around the SqlCommand object and since you're using ad-hoc queries, just use string.Format("sql test {0}", param). This way, you can reuse the SqlCommand object without having to clear the parameters.

The biggest issue I see here is that you've mixed the presentation layer with the business layer with the datasource layer. Dump the try...catch and allow the business layer to handle logging stuff. Return an object to the presentation layer and allow it to perform the redirects. Keep the datasource layer very simple... get the data and return an entity. The business layer can handle any business logic on the entity itself.

SQL Server not found could be your fault or the providers... if the provider is at fault often, change providers.

Chris Gessler
  • 22,727
  • 7
  • 57
  • 83
  • "Initial Catalog=database" says the database name is 'database'. Also, what's up with "Data Source=mywebsite.com"? Does mywebsite.com resolve to a known IP address of a SQL Server? – Chris Gessler Dec 29 '10 at 00:14
  • Although, there could be database with name 'database', my real database name is FirmaDMOZ. My real db domain name is mssql2005.turhost.com which resolves to IP. – HasanG Dec 29 '10 at 09:49
1

There are couple of inconsistencies which need to fixed:

  1. description = rdr["Title"]; no proper casting defined.
  2. Same command object is used for each sql statement and even you are not clearing parameters, it would be ideal if a separate command should be used for each sql statement.
  3. Too many redirections as well, it is best to handle redirection at the end of method.
  4. Check the database server health as well, it looks like database server is not responsive enough.

Hope it will help.

ShahidAzim
  • 1,446
  • 1
  • 10
  • 15
  • 1:I've cleared some code. 2:Why clear parameters if they are same? I just change values. An why consume resources while I can use same command for many actions? 3:I agree about redirects. 4:I can't it is shared hosting. – HasanG Dec 29 '10 at 10:31
  • 1
    Yes you are right same command can be used, but in-terms of debugging and code maintenance it would be a bit difficult. You may need to consider to change your hosting provider, as your site is quite big and to host on a shared server would be a problem. Who knows whose query has messed up the server! – ShahidAzim Dec 29 '10 at 16:42
0

Are you sure that the DB is configured to grant remote access using TCP?

David Weiser
  • 5,190
  • 4
  • 28
  • 35
  • Maybe the provider is having problems with the server but it is temporary. Max 10 min offline. Web site is now online: http://firmadmoz.com/ – HasanG Dec 29 '10 at 00:05