question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Oracle.ManagedDataAccess.Core new OracleConnection instances appear to create new OraclePoolManager instances that are never released

See original GitHub issue

Oracle.ManagedDataAccess.Core versions 3.21.1, 2.19.110 and 2.19.101.

It’s possible I am missing something/misunderstanding here and hopefully you could fill me in. (removed some content for data protection/brevity)

During each request to our API where needed we create a new connection as credentials are supplied via the caller of the API. This is done through a factory where we return a new instance of our “DirectDbConnection” object.

Factory Code:

OracleCredential oracleCredentials = GetCurrentCredentials();
var ora = new OracleConnection(_connectionStrings.SocialCareDirectConnectionString, oracleCredentials);
var DirectDatabaseConnection = new MosaicDirectDatabaseConnection(ora, _logger, _correlationIdService);
return DirectDatabaseConnection;

Direct Connection Code (removed logging and exception handling code):

public DirectDatabaseConnection(OracleConnection oracleConnection)
{
    _oracleConnection = oracleConnection;
}
    
public void Dispose()
{
    OracleConnection.ClearPool(_oracleConnection);
    _oracleConnection?.Close();
    _oracleConnection?.Dispose();
}

public IEnumerable<T> Query<T>(string query, bool buffered, int commandTimeout)
{
    IEnumerable<T> result = new List<T>();

    if (_oracleConnection.State == ConnectionState.Closed)
    {
        _oracleConnection.Open();
    }

    if (_oracleConnection.State == ConnectionState.Open)
    {

            result = _oracleConnection.Query<T>(query, buffered: buffered, commandTimeout: commandTimeout);
    }
    return result;
}

Our typical connection string looks like this and is pulled from config that is DI’d to the factory: Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=))(CONNECT_DATA=(SERVICE_NAME=)));

The connection is then used like so:

using var connection = _connectionFactory.GetInstance();
List<> result = null;
string query = "'";

var dbResult = connection.Query<>(query, buffered: true, commandTimeout: 60)
    .ToList();

result = MapDbResult(dbResult);
return new List<Actual>(result);

I’m sure that technically this is not an optimal approach in a performance manner, however situation states I need to fix with as little change as possible in the short term.

From my understanding connection pooling by default would only create a new connection pool if the connection string is in any way different. In my testing we’ve always used the same connection string AND credentials so form a connection pool standpoint it should always be the same if it exists. However the issue that is occurring is that the OraclePoolManager instances that are created when we create a new connection (it appears) are not being garbage collected. This led to the application reaching gigabytes of RAM usage overtime as this application is queried a lot by some dependent systems

Since there is no documentation on this internal class from what I can find it’s hard to understand why that may be.

Any insight you could shed would be greatly appreciated 😃

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:27 (14 by maintainers)

github_iconTop GitHub Comments

1reaction
alexkehcommented, Nov 4, 2021

@BashouT Clearing the pool removes the connections in the pool, but you still need a pool manager to manage the pool, which why it remains around.

Maintaining the same credential object is standard ADO.NET behavior. From the SqlClient connection pooling doc:

Different instances of SqlCredential will use different connection pools, even if the user ID and password are the same.

In general, ODP.NET tries to stay in line with standard ADO.NET provider behavior as that is what developers expect.

1reaction
BashouTcommented, Nov 4, 2021

@alexkeh why does this occur even if pooling is disabled? Even clearing the pools doesn’t release these connection managers/disposing the credentials objects. It still feels much like a bug.

Also it seems odd that you should have to maintain the credentials object to reuse when pooling is enabled. Shouldn’t the driver identify there’s a pool available for that credential pair even if the object is a different reference?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Oracle hangs on create OracleConnection Instance
Starting the same application from the console, it takes 2mins to create an instance of OracleConnection (not open the database!)
Read more >
Why would Oracle.ManagedDataAccess not work when ...
I have a database server listed in tnsnames.ora , sitting in my C:\oracle\11g\network\admin directory. If I tnsping this server I get the ...
Read more >
C# connect to Oracle database using Wallet
In SQL Developer the connection is made using an Oracle Wallet, but I have literally no idea how to utilize the wallet in...
Read more >
Object Referenced Not Set to an instance of an Object (in ...
I am using Nuget Package Oracle.ManagedDataAccess.Core 2.18.5 in a Asp.Net Core web api. I am able to run fine locally from both Windows...
Read more >
Could not resolve the connect identifier specified (oracle)
This issue is not related to our products. It seems that your Oracle Client library cannot establish a connection to the database server....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found