Our code is simple
using (var context = dbNewsEntities.CreateContext())
{
CheckClient(clientId, context);
var articles = context.GetArticlesForRSS(clientId, 0, ArchiveStartDays, false);
}
Randomly we get sql connection issues. I used windbg to check the SqlConnection, and indeed there are 100 (the default) connections in the pool.
However, when I use the method described here to check those connections, they are all closed. (as the _innerConnection object is System.Data.ProviderBase.DbConnectionClosedNeverOpened, not some methods that we were doing).
What going to happen when there are 100 closed connections in the pool? I assume c# code will just pick one other than create one. Am I right?
Many Thanks
Sorry, now I realised that our code is not as simple as I put there.
Turned out that there was some code hidden in another function, which wasn't closed properly.
If helps anyone, you can use:
SELECT
DBID,
DB_NAME(dbid) as DBName,
COUNT(dbid) as NumberOfConnections,
loginame as LoginName
FROM
sys.sysprocesses
WHERE
dbid > 0
GROUP BY
dbid, loginame
To see how how many connections in database, if your live system's exception is not properly catched, Then in windbg, you can use
.foreach (ex {!dumpheap -type System.Data.EntityException -short}){.echo "********************************";!pe ${ex} }
This will print you the exceptions and stack traces you need.
Related
There is a weird problem with a deployed Windows application that uses a remote connection string to SQL Server 2012.
When inserting records, the SQL Server times out after a relatively short time saying "The wait operation timed out". I'm not able to debug the deployed application to find out why it is happening and where in the code it is happening.
However, I don't get this error when using the same database on the development machine, with a local connection.
Generally the code used is:
void MapData( SqlTransaction transaction, Dictionary<int, IDataObject> items )
{
foreach ( var i in items )
{
transaction.Save( "CHECKPOINT" );
try
{
ImportItem( transaction, i );
}
catch ( Exception e )
{
transaction.Rollback( "CHECKPOINT" );
}
}
ReportStatus();
}
While this code has been working, I am uncertain about remote connections. We only have this one single case where it does NOT work.
What can it be?
Is there a more solid or performant approach than using Save() and Rollback() in a loop?
I don't want to use TransactionScope to spawn new "child" transactions.
Thanks!
Your transaction is taking too long (not sure if it's committing or rolling back). In order to understand why you'd have to run a trace to get performance metrics.
But to get it working you could increase your timeout. Set the SqlCommand CommandTimeout to a larger value or 0 (no timeout). Also, the connection timeout is used for the transaction timeout - usually an issue only on expensive rollbacks. You specify this in the connection string like Connection Timeout=30.
Some first things that people learned in their early use of MySQL that closing connection right after its usage is important, but why is this so important? Well, if we do it on a website it can save some server resource (as described here) But why we should do that on a .NET desktop application? Does it share the same issues with web application? Or are there others?
If you use connection pooling you won't close the physical connection by calling con.Close, you just tell the pool that this connection can be used. If you call database stuff in a loop you'll get exceptions like "too many open connections" quickly if you don't close them.
Check this:
for (int i = 0; i < 1000; i++)
{
var con = new SqlConnection(Properties.Settings.Default.ConnectionString);
con.Open();
var cmd = new SqlCommand("Select 1", con);
var rd = cmd.ExecuteReader();
while (rd.Read())
Console.WriteLine("{0}) {1}", i, rd.GetInt32(0));
}
One of the possible exceptions:
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.
By the way, the same is true for a MySqlConnection.
This is the correct way, use the using statement on all types implementing IDsiposable:
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
con.Open();
for (int i = 0; i < 1000; i++)
{
using(var cmd = new SqlCommand("Select 1", con))
using (var rd = cmd.ExecuteReader())
while (rd.Read())
Console.WriteLine("{0}) {1}", i, rd.GetInt32(0));
}
}// no need to close it with the using statement, will be done in connection.Dispose
Yes I think it is important to close out your connection rather than leaving it open or allowing the garbage collector to eventually handle it. There are a couple of reason why you should do this and below that I'll describe the best method for how
WHY:
So you've opened a connection to the database and sent some data back and forth along this pipeline and now have the results you were looking for. Ideally at this point you do something else with the data and the end results of your application is achieved.
Once you have the data from the database you don't need it anymore, its part in this is done so leaving the connection open does nothing but hold up memory and increase the number of connections the database and your application has to keep track of and possibly pushing you closer to your maximum number of connections limit.
"But wait! I have to make a lot of database calls in rapid
succession!"
Okay no problem, open the connection run your calls and then close it out again. Opening a connection to a database in a "modern" application isn't going to cost you a significant amount of computing power/time, while explicitly closing out a connection does nothing but help (frees up memory, lowers your number of current connections).
So that is the why, here is the how
HOW:
So depending on how you are connecting to your MySQL database you a probably using an IDisposible object to help manage the connection. Here is what MSDN has to say on using an IDisposable:
As a rule, when you use an IDisposable object, you should declare and
instantiate it in a using statement. The using statement calls the
Dispose method on the object in the correct way, and (when you use it
as shown earlier) it also causes the object itself to go out of scope
as soon as Dispose is called. Within the using block, the object is
read-only and cannot be modified or reassigned.
Here is my personal take on the subject:
Using a using block helps to keep your code cleaner (readability)
Using a usingblock helps to keep your code clear (memory wise), it will "automagically" clean up unused items
With a usingblock it helps to prevent using a previous connection from being used accidentally as it will automatically close out the connection when you are done with it.
In short, I think it is important to close connections properly, preferably with a con.close() type statement method in combination with a using block
As pointed out in the comments this is also a very good question/answer similar to yours: Why always close Database connection?
I've got an error in my C# application. I'm not sure if it's my program or my website. It's a gaming emulator and it says after 1-2 hours running 'Too many connections'. It also says it on my website.
The line this code is erroring on is below, and it errors and highlights the words connection.Open(); when it crashes. I think it has something to do with not closing the connections.
//C# Coding (In VB)
private static SqlDatabaseClient CreateClient(int Id)
{
MySqlConnection connection = new MySqlConnection(GenerateConnectionString());
connection.Open();
return new SqlDatabaseClient(Id, connection);
}
//Application error
[04:51] Exception - Session -> To many connection[]MySqlData.MySqlClient.MySqlPacket ReadPacket<> # at MysqlData.MySqlClient.MySqlStream.Readpacket<>
at MySql.Data.MySqlClient.NativeDriver.Open<>
at MySql.Data.MySqlClient.Driver.Open<>
at MySql.Data.MySqlClient.Driver.Create
at MySql.Data.MySqlClient.MySqlPool.GtPooledConnection<>
at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver<>
at MySql.Data.MySqlClient.MySqlPool.GetConnection<>
at MySql.Data.MySqlClient.MySqlConnection.Open<>
at Reality.Storage.SqlDatabaeManager.CreateClient in C:\iRP\SqlDatabaseClient.cs:line 24d
It's good practice to place the code accessing your database within a using clause. By doing this you will ensure that your connections are disposed of when it is not used anymore.
C# Too many connections in MySQL
Take a look at that link. You need to use the 'using' statement so the connections are opened and closed properly.
I'm hosting the WCF service as a managed Windows service, and I keep getting an AccessViolationException when the consumer/client invokes its method for a second, third or fourth time. The crashes are completely random, so sometimes it might not crash until several more invocations later.
Here's the code with syntax highlighting for easier reading: http://pastebin.com/Z3Z06944
See the comments around the private method "CheckUser", since that's where the exception might be occurring.
I had a look at the code you posted, and I don't see what this has got to do with WCF. You say that commenting out the code for invoking the FireBirdSql (FbCommand?) and the AV goes away. Clearly the problem is with FireBirdSql. Try updating to the latest version, or send the crash report to the developers. An AV (access violation) typically occurs with a problem in the p/invoke unmanaged code interop layer. It sounds like some kind of multithreading problem which would be brought out in a WCF scenario.
(update: edited OP question title to include FbSQL reference)
In your code you are not explicitly closing the connection.
Since you are using the using statement it will get closed but there may be a delay.
If there is a max number of connections and the requests are coming quickly, you could get an exception if the max number is reached.
This would explain the random nature of the errors.
Edit
Your code is vulnerable to an sql server injection attack, you should fix that.
Your problem could be a locking error, do you have an index on user and password, if not you are doing a table scan, which locks the table.
I'm thinking that there are better Role / Membership provider systems in place but based on your code, you could improve this with TRY/FINALLY contructs, with the using statement.
public Boolean AddUser(string user, string pass)
{
using (FbConnection con = new FbConnection(ConfigurationManager.ConnectionStrings["DBi"].ConnectionString.ToString()))
{
using (FbCommand fbComm = new FbCommand("INSERT INTO users (name, pass) VALUES ('" + user + "','" + pass + "')", con))
{
fbComm.Connection.Open();
if (CheckUser(user, pass, con) == 0)
{
fbComm.ExecuteNonQuery();
return true;
}
fbComm.Connection.Close();
}
}
return false;
}
Have a great day!
I have a ASP.net based application.
The CPU on the SQL Server box is constantly ~90 - 100%
There are a lot of inneficient queries, which I am currently working on, however, looking at the code from a previous coder, he never seemed to close (or dispose) the SqlConnection
When I run the folloing query, I get around 450 connections that are "Awaiting Command"
SELECT Count(*) FROM
MASTER.DBO.SYSPROCESSES WHERE
DB_NAME(DBID) = 'CroCMS' AND DBID != 0
AND cmd = 'AWAITING COMMAND'
Is this likely to be causing a problem?
I read this and it seems to relate:
http://www.pythian.com/news/1270/sql-server-understanding-and-controlling-connection-pooling-fragmentation/
We are also getting a lot of timeouts, specifically when replication is enabled..
I'm not sure if this is related.. Have disabled replication (transactional) for now and it seems ok..
(This server is a subscriber to our in office Database server)
Would disposing of the SQL connection object help?
Yes, dispose them. Otherwise ignore them for now. Possibly the pool is as large because the statements are slow. I would more suggest:
Fixing the statements.
Check the applicaion that it only uses one connection PER REQUEST (i.e. not open multiple at the same time).
If the problem does not get better after optiomizing SQL - you can revisit the pool.
You should always dispose the command object when your done with it. that way the connection pooling can be used better.
easist is to use the using statment.
using (
var sqlCommand = new SqlCommand(
"storedprocname",
new SqlConnection("connectionstring"))
{ CommandType = CommandType.StoredProcedure })
{
// do what you should.. setting params executing etc etc.
}