Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Oracle.DataAccess.Client.OracleException ORA-03135:连接失去联系_C#_.net_Oracle_Database Connection_Odp.net - Fatal编程技术网

C# Oracle.DataAccess.Client.OracleException ORA-03135:连接失去联系

C# Oracle.DataAccess.Client.OracleException ORA-03135:连接失去联系,c#,.net,oracle,database-connection,odp.net,C#,.net,Oracle,Database Connection,Odp.net,我有一个.Net服务,可以在每次请求时连接到Oracle数据库。它在开始时运行良好,但在一些请求之后,我开始收到: Oracle.DataAccess.Client.OracleException ORA-03135: connection lost contact at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErr

我有一个.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)
   ...

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

我也看到过这种情况;尝试在连接字符串中使用“pooling=false”关闭连接池。我有一个理论认为池中的空闲连接会过期,但ODP.NET没有意识到它们已经过期,然后,当您的应用程序抓取一个连接并尝试执行某项操作时,您会遇到该异常。

发生这种情况的原因是您的代码请求从Oracle连接池进行连接,而连接池返回到Oracle DB的断开连接/陈旧连接。ODP.NET本身不测试发送到客户端的连接的连接状态

因此,为了安全起见,您可以在执行连接时检查从池中接收的连接的
连接状态==Open

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

这两种方法都会对性能产生影响,因为它们会在每次需要连接到数据库时测试连接状态


我使用的第三个选项是使用异常。首先要乐观,使用连接池返回的连接。如果你得到一个ORA-3135,然后请求一个新的连接,并像执行while循环一样再次执行你的查询。在最好的情况下,您可以将第一个连接作为有效连接,然后执行查询。在最坏的情况下,池中的所有连接都已过时,在这种情况下,代码将执行N次(其中N是连接池大小)。

有人还建议在数据库跳转后执行此操作。出于好奇,您是否通过编程方式检查连接状态来解决此问题(即,如果已打开,则不执行任何操作)或在web.config中设置Validation Connection=true,或两者兼而有之?嗨@Luke,我在个人层面上“解决”了这个问题-我辞职去读博士:)呵呵,恭喜你,不幸的是我不能走这条路,不够聪明;)@卢克,说真的,你试过桑迪的第三个选项了吗?我想我应该从那里开始。我得到了一个示例web应用程序,它将练习和测试所有三个选项,以及它们的组合,只是等待批准。我会回来报告的,谢谢。我发现验证连接选项是一个很好的解决方案。它为我的应用程序平均增加了20%的开销。如果你做了很多琐碎的查询,它会更高。此外,检查连接状态也有一些开销,我认为这可能涉及到到到服务器的往返。在我的测试中,每次在代码中检查连接并不比只在连接字符串中设置Validate connection选项快多少,这就是为什么一开始就不检查连接的原因。用你现有的连接。如果当前连接失败,则获取新连接。当您说将验证连接放在连接字符串中时,您是在ORA文件中还是在app.config中?