我有一个在每次请求时都连接到Oracle数据库的.Net服务。它一开始工作得很好,但在一些请求之后,我开始收到:
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)
...你知道问题出在哪里吗?我处理所有的连接、结果和参数。这个服务的负载是非常低的。
发布于 2011-03-16 18:52:55
这是因为您的代码从Oracle连接池请求连接,而连接池返回到Oracle DB的断开连接/陈旧连接。ODP.NET本身不会测试发送到客户端的连接的连接状态。
因此,为了安全起见,您可以在执行Connection.Open()时检查从池接收的连接的connection status == Open。
或
让ODP.NET通过在web.config中的连接字符串中设置Validate Connection = true来为您执行检查。
这两种方法都会对性能产生影响,因为它们会在您每次需要连接到数据库时测试连接状态。
我使用的第三个选项是使用异常。首先,保持乐观,使用从连接池返回的连接。如果您获得了一个ORA - 3135,那么请求一个新的连接并再次执行查询,就像一个while循环一样。在最好的情况下,你可以得到你的第一个有效的连接,你的查询将被执行。在最坏的情况下,池中的所有连接都是陈旧的,在这种情况下,代码将执行N次(其中N是连接池的大小)。
发布于 2010-10-09 02:29:00
我也看到过这种情况;尝试在连接字符串中使用"Pooling=false“关闭连接池。我有一个理论,池中的空闲连接到期了,但是ODP.NET没有意识到它们已经过期了,然后当你的应用程序捕获一个并试图做一些事情时,你就会得到异常。
https://stackoverflow.com/questions/3370078
复制相似问题