this is my powershell code :
[void][System.Reflection.Assembly]::LoadFile("C:\DLL\Oracle.ManagedDataAccess.dll")
$OracleConnexion = New-Object Oracle.ManagedDataAccess.Client.OracleConnection('User Id=test;Password="test";Data Source=10.2.2.1/TEST')
$TimeOut = 60
$OracleConnexion.Open()
$Query=$OracleConnexion.CreateCommand()
$Query.CommandText="Select * FROM TEST"
$Query.CommandTimeout = $Timeout
$ExecuteRequete=$Requete.ExecuteReader()
while ($ExecuteRequete.Read()) {
$SiebelLastRecord += $ExecuteRequete.GetDateTime(0).ToString()
}
$OracleConnexion.Close()
So I'm opening ODP.NET connection with $OracleConnexion.open()
then closing it with $OracleConnexion.close()
is it sufficient to close properly my connection to Oracle Database? Or should I use $OracleConnexion.Dispose()
?
I execute my powershell every 5min via Task scheduler... So maybe Should I use Dispose() to avoid memory saturation?
It looks like everybody else, I noticed late that you're in powershell. In that case, it doesn't really matter. Everything is going to get cleaned up when the shell ends regardless. I suppose you could add a [catch] and maybe close/dispose the connection there if it's still open, but I think that would only be necessary if you planned on letting your script continue.
I'll leave my longwinded c# answer below. Even though it doesn't really apply to your script, it explains the difference (or lack thereof).
The short answer (for c#):
using (var conn = new OracleConnection(connectionString))
{
}
"using" ensures that .Dispose is called at the end of the block even if an exception is thrown. That way you never risk a connection being orphaned until garbage collection finally gets around to cleaning it up and that might be well after you run out of database connections.
The long answer:
Using a reflector, you will see that Dispose calls Close:
protected override void Dispose(bool disposing)
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry);
this.m_disposed = true;
this.m_dataSource = string.Empty;
this.m_serverVersion = string.Empty;
try
{
bool flag = this.m_connectionState == ConnectionState.Closed && this.m_oracleConnectionImpl == null;
try
{
if (!disposing)
{
if (!flag)
{
if (OraclePool.m_bPerfNumberOfReclaimedConnections)
OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.NumberOfReclaimedConnections, this.m_oracleConnectionImpl, this.m_oracleConnectionImpl.m_cp);
}
}
}
catch (Exception ex)
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
if (!flag)
{
try
{
this.Close();
}
catch (Exception ex)
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
}
try
{
base.Dispose(disposing);
}
catch (Exception ex)
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
try
{
GC.SuppressFinalize((object) this);
}
catch (Exception ex)
{
if (!ProviderConfig.m_bTraceLevelPublic)
return;
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
}
catch (Exception ex)
{
if (!ProviderConfig.m_bTraceLevelPublic)
return;
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
finally
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit);
}
}
Is there any real difference? No - the unmanaged resource IS the connection which is taken care of with .Close. You'd see no functional difference (other than delayed tracing) if you checked the connection status in a finally block and called .Close there if it was still open.
OracleConnection conn = null;
try
{
conn = new OracleConnection(connectionString);
}
finally
{
if(conn.State != ConnectionState.Closed)
conn.Close();
}
That said the recommended pattern for idisposible objects is to use a "using" block. Yes I suppose it is true that you have the option to reopen the connection with close, but I don't see that being a useful thing to do.
If you didn't use a using or a finally and an exception is thrown and close/dispose is never called, then freeing the connection to the db would be nondeterministic - Dispose(false) would happen whenever the garbage collector got around to it - and that might be long after you run out of connections to your db.
OracleConnection conn = null;
conn = new OracleConnection(connectionString);
conn.Open();
//exception occurs - Close is never called - resource leak!!
conn.Close();
Close closes the connection and allows you to reopen it again.
Dispose closes the connection if it hasn't been closed and also disposes of it so you can't reopen it again.
Use dispose - dispose frees up memory of a resource, if that resource is open, then a well behaved .dispose method will close the resource.
Dispose() vs. Close() with ConnectionPooling: https://community.oracle.com/thread/165664?start=0&tstart=0
More standard implementation for resource which implement IDisposable
is by wrapping it by using
:
using (OracleConnection connection = new OracleConnection(connectionString)){
using (OracleCommand command = new OracleCommand(sql, connection))
using (OracleDataReader reader = cmd.ExecuteReader())
{
}
connection.Close(); //optional
}
It is equivalent to implementing .Dispose
after the execution block. Internally, Dispose
will also handle the closing. Nevertheless, you could also call the .Close()
after the command block.
A sample in the oracle documentation which uses Oracle.DataAccess
encourages the use of Dispose
too.
I would wrap your connection by a using statement. When you're done with your connection then close it before adding the bracket. To be 100% safe I would do something like this:
using(OracleConnexion Con = new OracleConnection (...))
{
Con.Open()
...
Con.Close()
}
Edit:
I added the Con.Close()
, because in the past the dispose
was not implemented correctly in the ODP.NET. The connection was kept open. We had to force the connection to close manually and that's why in the example, I specify the Close
.
来源:https://stackoverflow.com/questions/35703559/how-to-properly-close-odp-net-connection-dispose-or-close