At the moment our code looks like this
public void Close(bool saveChange)
{
if ((_Connection != null) && (_Connection.State == System.Data.ConnectionState.Open))
{
_Connection.Close();
_Connection.Dispose();
_Connection = null;
GC.Collect();
}
}
Where GC.Collect() is needed to close file properly and remove all .ldb files.
Is it possible to close db file and immideately remove all temp .ldb files without calling GC ?
As every class implementing IDisposable, you should use the using-statement to dispose objects. On this way connections are also getting closed.
For example:
using(var conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + Server.MapPath("Pets/Pets.mdb")))
{
conn.open();
// do something with it
}
You should also read this because the way you're using connections can be improved.
As a rule of thumb: always create,open,use and close connections at the same place and let the ADO.NET connection pool manage the underlying connections.
If you have a Class that is using the Data in several entry-points.
and you HAVE to keep the connection open.
(hence can not use using(Connection x=...){} statement)
.
your class should also inherit IDisposable and implement
void Dispose()
{
this.dbConnection.Dispose();
}
the dbConnection.Dispose() will take care of closing the connection gracefully unless you need some custom actions performed (e.g. Logout, Save Cached Info, Etc...)
Anyway, i am in favor of #Tim Schmelter idea:
Close the connection after any transaction.
The Connections will be cached in the Connection Pool => insignificant performance impact.
Calling GC.Collect() may not be the best solution, as this method collects all the "garbage". You may find it very helpful to make use of the using keyword. e.g.
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
// Do work here.
}
Just right after your using block, the connection object will be disposed!
using connections, msdn
using keyword, msdn
connection.Close();
OleDbConnection.ReleaseObjectPool();
This solved it for me eventually
Related
I need a to get a bit of understanding in this, When you open a connection to a Database can you leave it open?
How does this connection close?
Is it good practise or bad practice?
Currently I have a request to a database that works no problem
oCON.Open();
oCMD.ExecuteNonQuery();
oCON.Close();
However Some of the examples that I have seen are something like this with no database close.
oCON.Open();
oCMD.ExecuteNonQuery();
How would this connection get closed?
Is this bad practice?
I was looking for a duplicate, as this seems to be a common question. The top answer I found is this one, however, I don't like the answer that was given.
You should always close your connection as soon as you're done with it. The database has a finite number of connections that it allows, and it also takes a lot of resources.
The "old school" way to ensure the close occurred was with a try/catch/finally block:
SqlConnection connection;
SqlCommand command;
try
{
// Properly fill in all constructor variables.
connection = new SqlConnection();
command = new SqlCommand();
connection.Open();
command.ExecuteNonQuery();
// Parse the results
}
catch (Exception ex)
{
// Do whatever you need with exception
}
finally
{
if (connection != null)
{
connection.Dispose();
}
if (command != null)
{
command.Dispose();
}
}
However, the using statement is the preferred way as it will automatically Dispose of the object.
try
{
using (var connection = new SqlConnection())
using (var command = new SqlCommand())
{
connection.Open();
command.ExecuteNonQuery();
// Do whatever else you need to.
}
}
catch (Exception ex)
{
// Handle any exception.
}
The using statement is special in that even if an exception gets thrown, it still disposes of the objects that get created before the execution of the code stops. It makes your code more concise and easier to read.
As mentioned by christophano in the comments, when your code gets compiled down to IL, it actually gets written as a try/finally block, replicating what is done in the above example.
You want your SqlConnection to be in a using block:
using(var connection = new SqlConnection(connectionString))
{
...
}
That ensures that the SqlConnectionwill be disposed, which also closes it.
From your perspective the connection is closed. Behind the scenes the connection may or may not actually be closed. It takes time and resources to establish a SQL connection, so behind the scenes those connections aren't immediately closed. They're kept open and idle for a while so that they can be reused. It's called connection pooling. So when you open a connection, you might not really be opening a new connection. You might be retrieving one from the connection pool. And when you close it, it doesn't immediately close, it goes back to the pool.
That's all handled behind the scenes and it doesn't change what we explicitly do with our connections. We always "close" them as quickly as possible, and then the .NET Framework determines when they actually get closed. (It's possible to have some control over that behavior but it's rarely necessary.)
Take a look at the Repository Pattern with Unit of Work.
A connection context should be injected into the class which operates commands to the database.
A sql execution class - like a repository class represents - should not create a connection. It is not testable and hurts the paradigm of SRP.
It should accept an IDbConnection object like in the constructor. The repository should not take care if behind the IDbConnection is an instance of SqlConnection, MysqlConnection or OracleConnection.
All of the ADO.NET connection objects are compatible to IDbConnection.
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 am creating desktop application in winform that will use Sqlite Database.
So I created Sqlite Helper class that uses System.Data.SQLite and each method of that Helper class opens and closes connection.
But now I also added ability to attach additional databases but after Connection is Closed, all attached databases gets lost.
To correct this I modified the class so that the connection is opened in constructor and remains open.
After the application ends, I want that connection to close without explicitly calling the Close method.
Any suggestions how to do that?
Keeping the connection open for the lifetime of your application is not a good way to go.
I suggest to not follow this route.
On the contrary, I will try to encapsulate the functionality to attach a database inside a method that could be called on the need to use basis.
For example:
private static void AttachDB(string fileDB, string aliasName, SQLiteConnection cn)
{
string sqlText = string.Format("ATTACH '{0}' AS {1}", fileDB, aliasName)
SQLiteCommand cmd = new SQLiteCommand(sqlText, cn)
cmd.ExecuteNonQuery();
}
then in your code
using(SQLiteConnection cn = new SQLiteConnection(GetConnectionString()))
{
AttachDB(#"C:\SQLite\UserData.sqlite3", "UserData", cn);
// Do your code here
}
Close should not disconnect your database but this will only work when .NET connection pooling mechanism is on. Make sure you have that enabled in your connection string:
Data Source=filename;Version=3;Pooling=True;Max Pool Size=100;
Depending on how your class is defined, you can use Dispose or a destructor. Or, explicitly call Close() at the end of the program (from within Main, after Run...).
In C# there is a special syntax for such situation:
using(var connection = new Connection())
{
//work with connection
}
it compiles to something like:
Connection connection = null;
try
{
connection = new Connection();
//your operations
}
finally
{
connection.Dispose();
}
on calling Dispose() you close connection.
lock (_connectionLock) {
if (conn == null) {
conn = GetOpenConnection(connectionString);
}
try {
PerformDbAction(conn);
} finally {
conn.Dispose();
}
}
I have run into a problem where multithreading can cause issues with null connections as they can be opened and closed by several threads running at once. I tried to solve the issue by locking the process (above, code simplified for clarity) but have found that this seriously slows down the performance.
I tried to get around this problem by using two separate locks for the creation/disposal of database connections and to perform database action outside of locking:
lock (_connectionLock) {
if (conn == null) {
conn = GetOpenConnection(connectionString);
}
}
try {
PerformDbAction(conn);
} finally {
lock(_connectionLock)
conn.Dispose();
}
}
Only I realized that the above doesn't work as another thread may try to perform a database action with a connection that has already been disposed by another thread.
Could anyone suggest an alternative or solution where I can safely lock access to the database connection strings without slowing everything down so much?
EDIT: Sorry for not including this previously, but the reason I am not just creating new connections and disposing of them immediately is that I am trying to avoid unwanted MSDTC escalation. In using GetOpenConnection I am reusing an existing connection as this is one of the things that triggers MSDTC escalation.
I have managed to avoid the escalation with the top code example, but it performs way too slow.
Simply don't have one shared connection variable. Instead, each time you need to do something, open a connection, use it, and close it as soon as you can. You don't need to use any locks in your code, and the connection pool will manage the real network connections to the database.
At the moment, you've essentially built a primitive connection pool containing exactly one connection, which means you've got no concurrency at all in the database (well, not per process).
I have a simple while loop that checks the database for inserts. If its in the loop too long my try catch gets "max pool size was reached" error. So at the bottom of loop I have a connectionclearallpools(); But that still doesn't solve it.
while (!quit)
{
connection to database strings timeout=400
read from database
connection.clearallpools();
}
Probably you are not closing your connections...you may want to use
while(!quit){
//do something here
using(var connection = GetMyConnection()){
//do your db reads here
}
//do validations and something more here
}
This would ensure your connections are disposed / closed properly.
Also, you do not need to clear your pools.
SQLConnection / DBConnection objects implements IDisposable. You may want to go thru these
Digging into IDisposable
C# Using Statement with SQL Connection
You most probably keep opening new connections in the loop.
Above the loop open the connection is a using statement and then use it in the loop. Also note the removal of the clearallpools:
using(create new connection)
{
while (!quit)
{
connection to database strings timeout=400
read from database
// connection.clearallpools(); REMOVE THIS!!!!
}
}
You're exhausting the connection pool. Following each read you should close the connection which will release it back to the pool.