代码之家  ›  专栏  ›  技术社区  ›  Grzenio

oracle.dataaccess.client.oracleexception ora-03135:连接丢失联系人

  •  8
  • Grzenio  · 技术社区  · 14 年前

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

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

    2 回复  |  直到 13 年前
        1
  •  12
  •   sandyiit    13 年前

    发生这种情况的原因是代码请求从Oracle连接池进行连接,而连接池返回到Oracle数据库的断开/过时连接。odp.net本身并不测试发送到客户端的连接的连接状态。

    为了安全起见,您可以检查 connection status == Open 用于在进行连接时从池接收的连接。open())

    让odp.net通过设置 Validate Connection = true 在web.config中的连接字符串中。

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

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

        2
  •  2
  •   William Gross    14 年前

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