I got this code:
try
{
using (OracleConnection c = new OracleConnection(globalDict[byAlias(connAlias)].connString))
{
c.Open();
using (OracleCommand recordExistentQuery = new OracleCommand("regular.IsExistent", c))
{
// here working on oraclecommand
}
}
} catch(Exception exc) { }
OracleConnection is class of devArt dotConnect for Oracle.
Will this code call c.Close() when it goes out of (OracleConnection c = new OracleConnection(globalDict[byAlias(connAlias)].connString)) { .... } ?
No, it will call Dipose(). A using block will implicitly call Dispose() on the object specified in the using statement.
But often times for a database connection, Dispose() handles the Close() functionality, releasing the connection/processId that keeps a connection.
I would also like to add that in the event of an exception somewhere in your //here working on oraclecommand (basically inside your using(...){ } statement, Dispose() will also be called.
By design, you should be able to make multiple to calls to an object implementing IDisposable. In your case, issuing a calling a call to Close() after your using block of code will simply do nothing, as the connection has already closed/been returned to the pool. Any additional calls after the object has cleaned up should just return and do nothing.
Related
I would like to understand what does Clearpool, Dispose, Close do in OracleConnection?
After exception occurs, I would like to get rid off the current connection and create a total new connection with the same connection string. How should I get rid off the old connection?
Should l clearpool firstly or dispose the connection? And what does clearpool vs dispose/close do?
My current code is like below:
public virtual void Dispose()
{
try
{
_connection.Close();
}
catch (Exception e)
{
}
finally
{
_connection.Dispose();
_connection.ClearPool();
_connection = null;
}
}
The easiest way to solve this is to create the connection inside a using block. Everything inside that block will be disposed whenever the block execution finishes. Also, do NOT leave a catch with no action inside. This might end on a silent exception that you will be not aware of.
using(OracleConnection conn = new OracleConnection("yourConnStr"))
{
//ALL YOUR LOGIC INSIDE
}
I want to properly dispose the SqlConnection object whenever i come out of the method. So im using the "using" statement as shown below.
public int Hello()
{
using(SqlConnection con=new SqlConnection(constring))
{
using(SqlCommand cmd=new SqlCommand(Query,con))
{
try
{
con.Open();
return cmd.ExecuteNonQuery();
}
catch(Exception ex)
{
throw ex;
}
finally
{
con.Close()
}
}
}
}
Now, what i want to know is, Will the above code
Dispose the Connection properly when an Exception is occured in ExecuteNonQuery.
Make sure we will not get any ConnectionPool issues
Make sure the data is returned properly
If an exception occurs in SqlConnection will it dispose the object?
Can anyone help me on this?
You don't need the try/catch if you're just going to throw it, just change your code to this:
public int Hello()
{
using(SqlConnection con=new SqlConnection(constring))
{
using(SqlCommand cmd=new SqlCommand(Query,con))
{
con.Open();
return cmd.ExecuteNonQuery();
}
}
}
and regardless of what happens, exception or not, the connection will get closed if it's open and disposed.
Dispose the Connection properly when an Exception is occured in ExecuteNonQuery.
Yes
Make sure we will not get any ConnectionPool issues
i guess you mean connections would be properly relieved after executing query. if that is your question than You should not by using this approach.
Make sure the data is returned properly
using has nothing to do with returning data
If an exception occurs in SqlConnection will it dispose the object?
Yes
though you can rewrite your code as
using(SqlConnection con=new SqlConnection(constring))
{
using(SqlCommand cmd=new SqlCommand(Query,con))
{
try
{
con.Open();
return cmd.ExecuteNonQuery();
}
catch(Exception ex)
{
throw;
}
}
}
You should not use the using statement for sqlconnection.
using(SqlConnection con=new SqlConnection(constring))
Better you use try,catch and finally block to close the connection. So even if exception occurs in try & catch the finally block will execute and close the connection if its open.
The reason behind this is, think of below situaion.
Create object of a class that handles all database operation
e.g. DBUtility objDB = new DBUtility()
the above statement creates object of class and also initializes the sqlconnection variable from the constructor.
Now i am using the object objDB for executing multiple queries one by one. For this it should initialize the sqlconnection object only once and use it for its whole life (life obj objDB).
In your case the sqlconnection will be initialized as and when the method is called.
So simply init the connection once and open/close it for each of your operations. Your connection will automatically disposed by Garbage collector when objDB is disposed.
I found that my codebase contains various data access code where I have used using statements in two different ways. Which is the better way if any and are these two methods different? Any problems that could arise from not instantiating the SqlConnection and SqlCommand in the using statement? Ignore the obvious inconsistency problem.
Method 1:
public int SampleScalar(string query, CommandType queryType, SqlParameter[] parameters)
{
int returnValue = 0;
SqlConnection objConn = new SqlConnection(ConnString);
SqlCommand objCmd = new SqlCommand(query, objConn);
objCmd.CommandType = queryType;
if (parameters.Length > 0)
objCmd.Parameters.AddRange(parameters);
using (objConn)
{
using (objCmd)
{
objConn.Open();
try
{
returnValue = (int)objCmd.ExecuteScalar();
}
catch (SqlException e)
{
Errors.handleSqlException(e, objCmd);
throw;
}
}
}
return returnValue;
}
Method 2:
public int SampleScalar2(string query, CommandType queryType, SqlParameter[] parameters)
{
int returnValue = 0;
using (SqlConnection objConn = new SqlConnection(ConnString))
{
using (SqlCommand objCmd = new SqlCommand(query, objConn))
{
objConn.Open();
objCmd.CommandType = queryType;
if (parameters.Length > 0)
objCmd.Parameters.AddRange(parameters);
try
{
returnValue = (int)objCmd.ExecuteScalar();
}
catch (SqlException e)
{
Errors.handleSqlException(e, objCmd);
throw;
}
}
}
return returnValue;
}
In the first snippet, if there are any exceptions that occur after the IDisposable object is created and before the start of the using, then it won't be properly disposed. With the second implementation, there is no such gap that could result in unreleased resources.
Another problem that can occur with the first approach is that you could use an object after it has been disposed, which is not likely to end well.
It's possible that you are ensuring no exception could possibly occur, and maybe you're not. In general, I would never use the first method simply because I don't trust myself (or anyone else) to never ever ever make a mistake in that unprotected space. If nothing else, I'll need to spend time and effort looking very closely to be sure that nothing can ever go wrong. You don't really gain anything from using that less-safe method either.
I always go with the second method. It's easier to read and understand what objects are being disposed of at the end of a given block. It will also prevent you from using an object that has been disposed.
If you not use using you don't dispose your objets no managed, and GC no dispose
GC dispose only objects managed and sql connection is not managed so you must dispose, using use dispose in the end
Second one is better. Please read http://msdn.microsoft.com/en-us/library/yh598w02.aspx last remark.
In first object stays in scope after it's disposal. Using it then is not good practice.
Per MSDN
You can instantiate the resource object and then pass the variable to the using statement, but this is not a best practice. In this case, the object remains in scope after control leaves the using block even though it will probably no longer have access to its unmanaged resources. In other words, it will no longer be fully initialized. If you try to use the object outside the using block, you risk causing an exception to be thrown. For this reason, it is generally better to instantiate the object in the using statement and limit its scope to the using block.
In regards to the following code:
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
code...
}
Is the SqlConnection initialized with "using" so it is dereferenced/destructed after the brackets?
Please correct my questioning where necessary.
using is a syntactical shortcut for correctly calling Dispose() on the object.
After the code in the braces is finished executing, Dipose() is automatically called on the object(s) wrapped in the using statement.
At compile time, your code above will actually be expanded to
{
SqlConnection sqlConnection = new SqlConnection(connectionString);
try
{
// .. code
}
finally
{
if (sqlConnection!= null)
((IDisposable)sqlConnection).Dispose();
}
}
You can see how it's a handy shortcut.
Yes. The using statement is just syntactic sugar, and is translated by the compiler into something like
SqlConnection sqlConnection;
try
{
sqlConnection = new SqlConnection(connectionString);
// code...
}
finally
{
if (sqlConnection != null)
sqlConnection.Dispose();
}
using is a language construct that takes an IDisposable and calls Dispose() on it.
So
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
code...
}
is roughly equivalent to
SqlConnection sqlConnection = null;
try {
sqlConnection = new SqlConnection(connectionString));
code ...
} finally {
if(sqlConnection != null) sqlConnection.Dispose();
}
When the sqlConnection variable goes out of scope (at the end of the bracketed block), the Dispose() method will automatically be called.
After the using statement it will exit the scope which it is available in. The objects Dispose method will be called, but the object won't necessarily be garbage collected at that time.
So what this means is that if you have items which are cleaned up (files closed etc.) in the object's Dispose() method, they will get cleaned up immediately after the using statement ends. If you have a finalizer (~YourClassName) in addition to this which does other things, you cannot guarantee that will get called at that time.
I have a IDbConnection for both Sql or Oracle connections. I have no problem to open it and then read data or save data through the connection. However, when the job is done, I tried to close the connection. Then I got a exception: "Internal .Net Framework Data Provider error 1".
Here are some codes to close the connection:
if (conn != null) // conn is IDbConnectin
{
if (conn.State == System.Data.ConnectionState.Open)
{
conn.Close(); // bung! exception
}
conn.Dispose();
}
conn = null;
Anything else I should check before safely closing the connection?
I know it might not sound like it solves your problem directly, but IDbConnection is IDisposable, so wrap your code that uses it in a using {} block.
Why?
You probably know that at the end of a using {} block, Dispose() is called. And, in every instance of IDbConnection, calling Dispose() will indirectly call Close(). But you get an additional bonus to using using that'll prevent you from running into this issue entirely -- by using using, you're forced to keep the creation, opening, closing, and disposal of the connection within the same context.
Most problems I found where people were running into your issue is when they use a Finalizer, or a separate thread to dispose of their connection objects. To me, there's an even bigger smell going on, where they're keeping their disposable objects alive for just a little bit too long, possibly sharing the connection between multiple members of the same class.
In other words, when you pass around the connection object, you might be tempted to write something like this:
class AccountService {
private IDbConnection conn;
internal AccountService(IDbConnection connection) {
this.conn = connection;
}
public Account GetAccount(String id) {
IDbCommand command = conn.CreateCommand();
conn.Open;
Account a = Account.FromReader(command.Execute(Strings.AccountSelect(id)));
conn.Close; // I remembered to call Close here
return a;
}
// ... other methods where I Open() and Close() conn
// hopefully not necessary since I've been careful to call .Close(), but just in case I forgot or an exception occured
~AccountService() {
if (conn != null)
{
if (conn.State == System.Data.ConnectionState.Open)
{
conn.Close();
}
conn.Dispose();
}
conn = null;
}
}
If you had used using, you wouldn't have even needed to think about using a Finalizer:
// IDbFactory is custom, and used to retrieve a Connection for a given Database
interface IDbFactory {
IDbConnection Connection { get; }
}
class AccountService {
private IDbFactory dbFactory;
internal AccountService(IDbFactory factory) {
this.dbFactory = factory;
}
public Account GetAccount(String id) {
using (IDbConnection connection = dbFactory.Connection) {
using (command = connection.GetCommand()) {
connection.Open();
return Account.FromReader(command.Execute(Strings.AccountSelect(id)));
}
} // via using, Close and Dispose are automatically called
}
// I don't need a finalizer, because there's nothing to close / clean up
}
There are exceptions to the using rule, especially if the construction of the disposable object is expensive, but 99 times out of 100, if you're not using using, there's a smell.
I think you call close method in other thread or in Finilize method. Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. In a finalizer, you should only release unmanaged resources that your class owns directly. If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. see here