We are using OpenAccess ORM version 2013.2.702.1.
While using this ORM in our application we are experiencing an issue with connections leaking. We are using this ORM with Sql Server 2008 and higher editions.
When querying a database using ExecuteStoredProcedure and ExecuteQuery methods from OpenAccessContext class, db connections are created but some of them are never disposed. The number of connections after two hours of execution can grow up to 1000. I believe this is caused by a leak of a SqlInternalConnectionTds objects. The number of the SqlInternalConnectionTds instances is growing constantly, but the number of SqlConnection and PooledConnection instances stays almost the same. The diagnostic information was collected using dotMemory and standard Visual Studio Diagnostics tools. (Screenshots are attached)
Things that I should mention as well:
1) Our application works in multithreaded environment. Multiple threads can use the same context instance to execute stored procedures and queries.
2) When we are using Connection property (Context.Connection) to obtain a connection and execute our custom command we have used code example from this question http://www.telerik.com/forums/check-connection-state-vs-not-checking-connection-state. We are disposing connections in finally block, but connections are still leaking. As a side note, if we trying to obtain a StoredConnection (causing unpooling) and dispose both OAConnection and SqlConnection objects in finally block, connections leaks are stopped, but in this case error occurs while calling SaveChanges.
3) When we have used SqlConnection (new SqlConnection(connectionString)) and perform the same set of operations we didn’t find any issues related to connections leaks. All occurrences of ExecuteQuery and ExecuteStoredProcedure were changed to use SqlConnection except of OAConnection in this case.
4) Garbage collector is used very frequently and there is a lot of memory consumed by Generation 2. There are a lot of objects from Telerik.OpenAccess.Metadata namespace. These metadata objects hold references on dictionaries and other collections from system namespace, so we have a lot of leaked objects there as well.
<add key="ConnectionPool.Pool" value="Integrated"/>
<add key="ConnectionPool.ActiveConnectionTimeout" value="6000"/>
<add key="ConnectionPool.BlockWhenFull" value="true"/>
<add key="ConnectionPool.Reserved" value="1"/>
<add key="ConnectionPool.MaxActive" value="100"/>
<add key="ConnectionPool.IsolationLevel" value="ReadUncommitted"/>
<add key="ConnectionPool.Integrated.TestInterval" value="240"/>
<add key="ConnectionPool.Integrated.MaxIdle" value="10"/>
<add key="ConnectionPool.Integrated.MinIdle" value="2"/>
<add key="ConnectionPool.Integrated.TestOnAlloc" value="false"/>
<add key="ConnectionPool.Integrated.TestOnRelease" value="false"/>
<add key="ConnectionPool.Integrated.TestOnException" value="true"/>
<add key="ConnectionPool.Integrated.TestWhenIdle" value="true"/>
<add key="ConnectionPool.Integrated.MaxConnectionAge" value="0"/>
<add key="ConnectionPool.Integrated.ConnectRetryCount" value="30"/>
<add key="ConnectionPool.Integrated.ConnectRetryIntervalMSec" value="1000"/>
<add key="ConnectionPool.Integrated.PreparedStatementCacheEnabled" value="true"/>
<add key="ConnectionPool.Integrated.PreparedStatementCacheMax" value="0"/>
context.ExecuteQuery<T>("spGetResources", CommandType.StoredProcedure, parameters);
using (var connection = Context.Connection)
using (var command = connection.CreateCommand())
command.CommandTimeout = timeout;
command.CommandText = sql;
using (var rdr = command.ExecuteReader())
Can you help me to understand why connections disposing does not work properly if queries are executed using OpenAccessContext?
Also could you please advise why there are too many metadata objects are allocated?
Thanks in advance and let me know if you need more info.