C# MySQL Connection Pooling - c#

I am having C# multi threading application and using MySQL with single connection to whole application. But when two or more thread try to access database at the same time, then i get below error :
There is already an open DataReader associated with this Connection which must be closed first.
My Connection code is below
public static _connectionSetup = new MySqlConnection("Server=server ; Database=database;User ID=user;Password=pass;Pooling=true;");
and when i need to use connection i am using below code :-
using (MySqlConnection connection =_connectionSetup )
{
using (MySqlCommand command = new MySqlCommand("proc", connection))
{
....
}
}
I tried used pooling=true and i have create two separated connection as well for two different thread, but still i am getting above error.
Am I missing something?
How can I implement connection pool so that all thread will use separate connection and won't cause any issue?

Pooling is turned on by default, so you don't need that connection string parameter.
Don't share MySqlConnection instances. That's it.
Pooling is not something you implement in your code, it's done for you by ADO.NET.

Related

Is there an advantage to creating a new SQL connection for each query?

I am trying to design an efficient application that connects to a SQL Database and I was wondering what the merits/demerits of creating a SQL connection for each SQL query is,
Eg, Like the code below, making a class with the connection set once so you can call on it when ever you need it in the class.
class SqlQuery
{
SqlConnection Connection = new SqlConnection(#myConnectionString);
public void fillInfoData()
{
SqlCommand updateCommand = new SqlCommand(
#"my sql query", Connection);
Connection.Open();
updateCommand.ExecuteNonQuery();
Connection.Close();
}
}
Or should you create a new connection for each new query?
EDIT: Jon Skeet recommended creating a new connection for each query,
I was wondering why?
EDIT No 2: He stated it in this answer.
You open a connection per query and then when you close it, it goes back to the connection pool and the framework will manage the rest
So you do not have to worry about keeping connection alive, timeouts etc...
MSDN Article
https://msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.110).aspx
I think what he meant was not to keep a global connection object that is open. But you need to create an SqlConnection when you need it, execute all the queries needed at the point (Not a single connection per each query) and then close the connection.
So if you have a bunch of queries that needs to be executed, you don't need a single sql connection for each but one is only enough. But if you're executing a query each time the user clicks a button for example, it's better to open a connection on each click, because that way it is easier to manage closing and disposing the connection.

What if i don't close database connection in disconnected mode

I am doing windows forms application with connection to SQL Server (disconnected mode). Every action I handle in my application needs the connection. So I don't know where to close the connection.
I am asking what if i don't close the connection. I know that there is no runtime error that appears. But is there any other error that could appear?
There is a risk that if you are using the same connection for each method, from a private field or GetConnection() method etc.; you could end up trying to read/write when the connection is still open.
This could then throw errors and you could end up in a whole heap of it, if using a live SQL database.
If you can, create a new instance of a connection in a using statement each time you want to access the DB.
Like this:
var connectionString = "YourConnectionStringToTheDB";
var queryString ="YourSQLQueryHere"; // FROM * IN tbl SELECT * etc...
using (SqlConnection connection = new SqlConnection(
connectionString))
{
using (SqlCommand command = new SqlCommand(queryString, connection))
{
command.Connection.Open();
command.ExecuteNonQuery();
}
}
This way it is closed and disposed of when the code runs outside of the using statement's scope.
Notice that the SqlCommand is also in a using statement, as it too can be disposed of.
This is cleaner code and marks the objects for disposal by the Garbage Collector. (Google is your friend) - BIG topic; a lot of stuff to read.
Here is a similar question which gives you some more detail: The C# using statement, SQL, and SqlConnection
EDIT
Better still, you could wrap your SQL code in a try { } catch { } block to handle any errors at runtime.

What is the best practice in ASP.NET for re-using a database connection for MS Access migrating to SQL server?

What is the best practice for opening and re-using a database connection in an ASP.NET web service (C# 4.0) that has about 5 web methods that use the same database? The answer ideally will be the same for MS Access and SQL server.
Global private variable:
a. Advantage: Easy to maintain if change database providers
b. Disadvantage: Cannot use the ‘using’ clause and connection may stay open too long – how long will connection stay open approximately?
Pass the db connection as a method parameter:
a. Advantage: can close connection when not needed use ‘using’ clause
b. Disadvantage: annoying to maintain and pass param everywhere
Open and close the connection with using clause on demand when needed in any method:
a. Question: Is this the slowest because you have to re-open the same connection multiple times? OR because of behind-the-scenes connection pooling this is not slower? Thus this would probably be the best practice…?
b. Question: Is connection pooling only relevant for SQL server, thus would not work for MS Access?
At first I was thinking of using a global private variable (OleDbConnection) as I use the connection to the main database a fair bit in the web methods and supporting methods and will be migrating from MS Access to SQL server in the near future and will be easy to make the change.
But after reading up on some articles like Obtaining SQL connection most efficiently when using ASP.NET and web services
it seems like I can just create a new connection on demand anywhere with the ‘using’ clause and not suffer a performance hit?
ASP.Net pools database connections so you tend not to have to worry about these low-level details. Take a look at Tip 3 of this MSDN article.
Best practice is to not re-use your Connection objects at all.
public void GetEmployees() As List<Employee> {
var employees = new List<Employee>();
using (var connection = new SqlConnection(Configuration.ConnectionString)) {
using (var command = connection.CreateCommand()) {
command.CommandText = "SELECT * FROM dbo.Employee";
connection.Open();
using (var reader = command.ExecuteReader()) {
while (reader.Read()) {
employees.Add(Employee.CreateRecordFromOpenReader(reader));
}
}
}
}
return employees;
}
Then if you need transactions from whatever uses this, setup DTC and do this.
using (var scope = new TransactionScope()) {
var employees = GetEmployees();
employees.Map((e) => e.Status = Status.Active);
scope.Complete();
}

TransactionScope error saving a lot of information

I am developing a .NET web application with C# and SQL Server as database, being newbie for both technologies. I have a problem when I attempt to save a lot of information at the same time.
My code is simple:
SqlConnection cn = null;
try
{
using (TransactionScope scope = new TransactionScope())
{
using (cn = Util.getConnection())
{
cn.Open();
BusinessObject.saveObject1(param1, cn);
BusinessObject.saveObject2(param2, cn);
BusinessObject.saveObject3(param3, cn);
BusinessObject.saveObject4(param4, cn);
...
scope.Complete();
}
}
I always use the same connection object because if an error happens, I must revoke any change in my data and the same behaviour if the process is ok, is needed.
I don't mind it the process of saving takes a lot of time, in my application is perfectly normal because I have to save a lot of information.
The weirdness here is:
When I execute this function in the same local area network of the database, it perfectly works.
However, if I execute it from outside, such as, connected by a VPN and consequently with higher latency, I get an error with the message: "The transaction associated with the current connection has completed but has not been disposed. The transaction must be disposed before the connection can be used to execute SQL statements."
I have tried to change the timeout of the database through the connection string in the web.config but it didn't resolve anything. Also, if after each executeNonQuery() statement I do a cn.Dispose(), I get an error in the next attempt to use the connection object.
Do I have to change the parameters of TransactionScope object? Is there another better way to do this?
Thanks in advanced.
This is due to a timeout error. The TransactionScope might decide to rollback the transaction in case of a timeout.
You need to increase the timeout value in the TransactionScope constructor. The default max. timeout is 10min.
Move scope.Complete(); outside the connection block (MSDN article).
Did you try setting the Timeout = 0 in your Util.getConnection() function ? A value of 0 indicates no limit. This will complete the job surely. By setting the Timeout = 0 will complete every long operation job.

Start and close SQL connection - At start and in the end or every time needed?

I'm making a web application in C# with ASP.Net, and I'm using an SQL database for it. In the guides I saw (about SqlConnection and SqlCommand) they open and close the SQL connection each time they want to send a query. But I'm not sure this is the best way to handle the connection, because I also learned some PHP, and as far as I know in PHP you open a connection only once, at start. So what is the best way to handle the connection?
You should generally have one connection, and transaction, for the length of the web request.
If you have two connections, you could potentially have inconsistent data. e.g. in the first query you check the bank balance, then you close it. You then add $5 to the balance and save that away in the next connection. What if someone else added $5 between the two connections? It would go missing.
The easiest thing to do is to open the connection global.asax BeginRequest and save that away into the HttpContext. Whenever you need a connection, pull it from there. Make sure that you .Close the connection in your EndRequest
Also, read up here on connection pooling: http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx
It is not 'expensive' to repeatedly open and close connections, provided the username is the same each time.
Ado.Net has connection pooling already managed for you, so you don't need to worry about reusing connections.
You could use the Using statement to close and dispose connection:
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection("my_connection_string"))
{
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * from Table", conn))
{
conn.open();
adapter.Fill(dt);
}
}
Normal practice in .NET is to open a SqlConnection and use a SqlCommand, then dispose of both of them.
using(SqlConnection connection = new SqlConnection("myConnectionString"))
{
using(SqlCommand command = new SqlCommand("dbo.SomeProc"))
{
// Execute the command, when the code leaves the using block, each is disposed
}
}
As a connection to database is an expensive resource it's better to open sql connection as late as possible and close early. So you should open the connection just before executing a command and close it once you have executed it.
On the other hand if you are going to execute many commands in a short interval of time it's better to open the connection once and close after all the commands are executed.
For starters they do not as there is a connection pool that is being used, but SqlCommand has an overload to take a connection object, so you could keep the connection around and pass it.
Generally:
using (var ts = new TransactionScope())
{
using (var connection = new SqlConnection(...))
{
using (var command = new SqlCommand(connection, ...)
{
...
}
using (var command = new SqlCommand(connection, ...)
{
...
}
}
ts.Complete();
}
Of course I would recommend using LINQ-to-SQL or EF at this point.
Try Data Access Application Block in the Enterprise Library if you do not want to worry about opening and closing the connections.

Categories