Oracle.DataAccess.Client.OracleException ORA-03135:连接丢失联系

我有一个.Net服务,可以在每次请求时连接到Oracle数据库。 它在开始时工作正常,但在我开始获得一些请求之后:

Oracle.DataAccess.Client.OracleException ORA-03135: connection lost contact at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure) at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src) at Oracle.DataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior) at Oracle.DataAccess.Client.OracleCommand.ExecuteReader() at MyApp.Services.OracleConnectionWithRetry.ExecuteReader(OracleCommand command) ... 

知道可能是什么问题吗? 我处理所有连接,结果和参数。 这项服务的负担非常低。

这是因为您的代码从Oracle连接池请求连接,并且连接池返回与Oracle DB的断开连接/陈旧连接。 ODP.NET本身不会测试发送给客户端的连接的连接状态。

所以为了安全起见,要么检查connection status == Open连接时从池接收的连接connection status == Open ()

要么

让ODP.NET通过在web.config中的连接字符串中设置Validate Connection = true来为您进行检查。

这两种方法都会影响性能,因为每次需要连接数据库时都会测试连接状态。

我使用的第三个选项是使用例外。 首先要乐观并使用从连接池返回的whateven连接。 如果你得到一个ORA – 3135然后请求一个新连接并再次执行你的查询就像一个while循环。 在最好的情况下,您可以将第一个连接视为有效,并且您的查询将执行。 在最坏的情况下,池中的所有连接都是陈旧的,在这种情况下代码将被执行N次(其中N是连接池大小)。

我也看到过这种情况; 尝试在连接字符串中使用“Pooling = false”关闭连接池。 我有一个理论认为池中的空闲连接到期,但是ODP.NET没有意识到它们已经过期,然后当你的应用程序抓取一个并尝试做某事时你会得到该exception。