I am currently working on a C# (.NET) project which connects to a MySQL Community Server database and runs some queries. There are currently 4 classes which use their own MySQLConnection object (I'm using the MySQL .NET connector), in order to connect to the database.
Is this good practice, or should I use one 'global' (static?) connection? Using one single connection is kind of against my habits of structuring the code. Not a big fan of 100000 objects working with one shared static field. I bet it's against most programmers' views too.
I also noticed that once I call connection.Close(), the connection does not necessarily get closed. Trying to .Open() it again would result in an exception. I trust this is because I did not set "Pooling=False" in the connection string. I'll experiment with it. If you have any thoughts on this one too, feel free to drop them here.
So, in short, I'd like some opinions on how to organize my MySQLConnections. If you think a single static MySQLConnection to be used by all of the program's classes is better (not necessarily performance-wise, I'm talking more about the effect of multiple MySQLConnections on the database system itself), let me know why you think so.
I'm expecting for the final program to have around 10 or 15 classes, each actively querying the database.
My rules of thumb are:
keep connections open for as brief a time as possible
let ADO.NET handle connection pooling for you
share connections only when the processes are particpating in a transaction together
So, no you should not use one global static connection. But you could have a utility method that supplies your data fetching methods with an open connection. Then you would do something like (assuming Sql is your utility class):
public IEnumerable<MyClass> GetSomeData()
{
using (var cn = Sql.GetOpenConnection())
{
//get your data here
}
}
You can continue with one connection per class. Most ADO.NET providers use connection pooling per default as you have noticed. Close doesn't really close the connection but return the connection to the pool. However, you should not try to Open() the connection again but create a new connection object.
There is one downfall with using one connection per class and that's transaction handling. Transactions can not be shared over multiple connections (unless you are using TransactionScope).
I usually prefer one connection per "session" and take in the connection in the constructor to my repository classes. (As I usually use inversion of control containers). Google a bit about Unit Of Work implementations.
Do not create a single shared connection. Open as late as possible and close as early as possible. If you need to use a connection for multiple queries, try looking at MARS (multiple active record sets) I don't know if MySQL connector supports that though.
certianly let the system handle connection pooling. db connections are expensive.
public class DALCommon
{
public static string GetConnectionString
{
//return System.Configuration.ConfigurationManager.AppSettings["connectionInfo"];
get
{
NameValueCollection appSettings = ConfigurationManager.AppSettings;
string server = appSettings["server"];
string userid = appSettings["userid"];
string password = appSettings["password"];
return String.Format("server={0};user id={1}; password={2}; database=dbmystock; pooling=false", server, userid, password);
}
}
}
Related
Could I store a SqlConnection in the HttpContext?
I mean, how can I share a single SqlConnection across multiple classes?
In my project every class inherits a base abstract class that open and close connection.
This class recognizes if a SqlConnection was opened by another class in that case uses it.
I can store this connection in another way that isn't HttpContext?
There is another method to do this, exp. pass the connection between layers?
THX
I wonder why you need to store a single SqlConnection. It doesn't smell great.
If you really do need to share a single SqlConnection across multiple classes, dependency injection is likely a better option. Have a connection factory instantiate a connection object and pass it around as required.
Otherwise, let the DBMS worry about controlling your connection resources. Create, open and close a connection each time you need one.
You are going wrong way. You shouldn't follow this thinking unless you need to share transaction context as mentioned by Lasse V. Karlsen mentioned in his comment. If you are worried about performance and thi is the reason why you want to keep one connection open and shared then it also wrong. In case of e.g. ADO.NET you have connection pooling. This means that even though you call close on connection it is not closed, it is returned to the pooler. This is a mechanism that keeps track of connections and maximizes efficiency by managing them. If you call Open to get a new connection then under the hood you may get an existing one that was used a few minutes before and that was still kept open by the pooler and returned back for reuse. So, if the motivating force is efficiency, then it is not a path you should follow. It is already taken care of on a lower level. Refer to http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx .
I am currently working on a MVC 4 project and we decided to use plain old SQL and to not rely on EntityFramework.
My question now is what is the best practice to initialize a database connection. I thought about using a Singleton that opens the connection (the connection-string is stored in the Web.config) and then use the established connection throughout the application life-cycle but I'm not sure if this is a good approach!
For database connection, Open as late as possible and close as early as possible.
Instead of having a singleton connection, you should create connection object when ever it is necessary, and better if you use using block, since Connection implements IDisposable and you should get dispose the connection when you are done with it.
ODP.NET supports connection pooling so there is no reason (Unless proven otherwise in your specific case) to keep a Singleton of your OracleConnection object.
The best practice here is imo to use a connection (.NET connection object, not a physical connection) for each statement.
using(OracleConnection connection = ...)
{
...Do work here
}
If you want to know more about a similar approach to what you've just described, look here: https://stackoverflow.com/a/10153406/1289283 . I've already answered that kind of dilemma. Be sure you won't do this on per-application scale, but rather on per-request, otherwise you get into troubles. Per-application is fine for single-user-desktop apps, NOT for webapps! And do not use singleton for this also...
What is best practice for C# Window Forms and SQL connection instance. I need the same SQL connection in all window forms. What is best implementation practice for this? Where do I put the SQL connection?
I am using Compact framework 3.5.
Personally I prefer to leave connection management to the ADO.NET connection pool and everytime I want to query:
using (var conn = new SqlConnection("connection string"))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT id FROM foo;";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// ...
}
}
}
When you call conn.Open() a physical connection is not opened, it is drawn from the connection pool, and when the using block end and invokes .Dispose the connection is not closed but returned to the connection pool in order to be reused. This improves performance and relieves me from worrying about where to put or store those SqlConnection instances in applications.
You say you need the same connection in all your forms, but I don't think you should consider that to be axiomatic. You may well need to connect to the same database in all forms, but that's not the same thing - any more than you would need to use the same connection to make multiple requests to a web service.
I would strongly suggest three things:
Use dependency injection to allow a single object to be provided to multiple classes/objects which all need it
Don't inject the actual connection: inject something which can provide a connection, or perhaps just something which can execute a query for you.
Take code which accesses the database out of the user-interface code so you can test each independently of the other.
Generally speaking, database access should be (from the caller's point of view): "open connection, do work, close connection whatever happened" (as per Darin's answer). Let .NET's connection pooling take care of the physical connection to the database. How you structure your code around that will depend on your requirements, and the extent to which they vary between forms. In many cases you may be able to get away with just asking your database access class to execute a query for you with a certain set of parameters and return the results - in other cases you may need more fine-grained control.
As Dimitrov suggested a good approach is to open and close connections only when needed and keep it open the shortest possible time. .NET Connection pool will handle this for you so connections will be reused in a transparent way for you.
In general a good approach is to have another class library to serve as Data Access Layer which wraps the calls to database and does not expose any connection or command usage to the UI, so in the future you would be able to move to another database engine, if needed, changing only the DAL.
Communication from DAL and UI should consist only in objects (entities) or for simple projects DataTables and DataSets. In most of the cases a third project (class library) is in the between and it's called Business Logic, such level manipulates the data from DAL and applies your application specific business logic returning cleaner or elaborated results to the UI.
I have used this approach in many projects already, since about 11 years.
You should make a class with the connection logic in.
I am new to databases and linq, so my problem may be considered trivial. I currently start all my db requests in each class with:
DataClassesDataContext db = new DataClassesDataContext()
Then I proceed to make whatever linq request I need within the method and carry on with the main application logic.
Now, two interesting queries:
1) I believe I have seen people wrapping db usage within 'using'. Such as:
using (DataClassesDataContext db = new DataClassesDataContext())
{
...
}
If this is correct, then doesn't it mean that my class can't use a member 'db' variable anymore, but rather those db requests need to be made within each function call? Also, what exactly would happen if I don't use 'using' within the calls?
2) Running my app with SQL Profiler enabled, I see lots of connections opening and closing. Does this means that each DataClassesDataContext call makes a separate connection? It seems inefficient, so is the right way to actually make the DataClassesDataContext object a static within each class being used?
In general, you should use one DataContext per database conversation. Only you can decide exactly what a conversation is, but typically it is a complete request (fetch the user's wish list, or fetch the user's closed orders, for example) that you might think of as a "unit of work."
Typically what happens is something like this:
WishList wishlist;
using(var context = new DataContext(connectionString)) {
var service = new UserWishListService(context);
wishlist = service.GetUserWishList();
}
Also, what exactly would happen if I don't use using within the calls?
The DataContext won't be disposed of properly (unless you've wrapped in a try-catch-finally, but generally you should just use using).
Does this means that each DataClassesDataContext call makes a separate connection?
Not quite. Your application will benefit from the SQL Server ADO.NET provider's built-in connection pooling. Don't worry about this, let the provider manage it for you.
It seems inefficient, so is the right way to actually make the DataClassesDataContext object a static within each class being used?
Absolutely not. DataContexts are not thread-safe (in fact, they are thread-unsafe) and this has "there be dragons" written all over it. Additionally, even a single-threaded context, a static DataContext is a bad choice because the DataContext maintains a cache (for object tracking purposes) of all the entities it has pulled from the database. Over time, the memory consumption will become ginormous.
Since you added the asp.net tag, it means you are using the context within a HTTP call. A static member context is unusable in asp.net because you need to synchronize access to it, and since your data context is required by every call, you can only serve one HTTP response at a time, a scalability fiasco of epic proportions.
This is why data context are created and disposed 'on-the-go'. In fact, the class specifications clearly calls out this use pattern:
In general, a DataContext instance is
designed to last for one "unit of
work" however your application defines
that term. A DataContext is
lightweight and is not expensive to
create. A typical LINQ to SQL
application creates DataContext
instances at method scope or as a
member of short-lived classes that
represent a logical set of related
database operations.
For ASP.Net a sensible 'unit-of-work' context is the HTTP call itself. A longer discussion on this topic can be found at Linq to SQL DataContext Lifetime Management.
The issue of connections open/close is a non-issue. Normally the connections are pooled and the 'opening' is nothing but a re-use of a connection from the pool. If you're opening is heavyweight (fully fledged login) then you're using pooling incorrectly. Comparing Logins/sec and Connection Resets/sec counters will quickly reveal if that is indeed the case.
Today I've implemented a nasty hack in my code where every request to the database opens it's own connection due to the fact that I couldn't find any way to enable MARS (multiple active record sets) when communicating with a MySQL database.
In my C# program I do a lot of parallel work, which isn't a problem regarding databases such as MSSQL 2005 and 2008 (append ;MultipleActiveResultSets=true to your connection string) and SQLite (supports it "out of the box") and you are able to retrieve two datasets from the database at the same time.
Things that I do know: it's expensive to open a connection to the database and their for I would like to keep these to a minimum.
Any suggestions?
Maybe a best way to handle this scenario type is to implement that parallel data processing into your database, by using a store procedure or a cursor, so you don't need to deal with a very specific database feature.
Any suggestions?
I don't know if there really is no way to enable MARS with MySQL, but if that's correct, then my best suggestion is to implement connection-pool.
Look at the MySQL documentation for connection string parameters (no MARs) -
http://dev.mysql.com/doc/refman/5.5/en/connector-net-connection-options.html
Things that I do know: it's expensive to open a connection to the database and their for I would like to keep these to a minimum.
Utilize connection pooling all the way! (just make sure you use the exact same connection string each time).
Mysql doesn't support MARS,instead you have to save the data and close the reader or use another connection for the new reader.