ODP.NET:使用连接池避免连接超时

时间:2010-12-09 14:22:28

标签: .net oracle connection-pooling odp.net

在一个站点,我可以使用SQL Developer连接到Oracle数据库,让它闲置很长时间(例如,> 60分钟),然后返回,这很好。在第二个站点,如果它保持空闲超过5-10分钟(我没有完全计算),它会使SQL Developer处于新操作超时的状态,我需要手动“断开连接”,然后按顺序重新连接做任何有用的事情。这似乎是第二个站点的连接超时,我不知道是什么导致它(我想知道如何关闭它,虽然这不是我的主要问题)。

我的程序使用ODP.NET并处理spurts中的数据。每隔30分钟(为了讨论),它将获得一堆要处理的数据,这将涉及许多重复的连接。它还使用连接池。我已将连接池设置为使用5分钟的生命周期。

我在第二个站点(而不是第一个站点)看到的是我的程序将在每次突发数据开始时获得连接超时异常(例如,ORA-03113)。我认为正在发生的是,在数据突增期间,连接池按设计使用。在突发结束时,将检查“连接生命周期”,并且连接不会太旧,因此它将保留在连接池中。然后,30分钟后,当新数据到达时,连接将从池中取出(并且不会检查生命周期或超时)并使用,并且正在超时,正如我在SQL Developer中看到的那样。

如何避免连接超时,但在喷射过程中仍然可以利用连接池?从文档(和我的经验)看来,连接仅在进入池时检查Lifetime,而不是在它出现时检查。

3 个答案:

答案 0 :(得分:3)

这是一个非常古老的问题,但我在应用程序中遇到了一些类似的问题,所以我认为一些信息可能会帮助其他任何人在这个问题上徘徊。

TL; DR摘要是ODP.NET驱动程序和.NET实现彼此不能很好地协作,因此您正常运行的铣削连接池设置似乎无法正常工作你会期待的。

  • 连接生命周期是主要攻击者。我不确定this blog是否仍然适用,因为它已经很老了,但我还没有发现任何文件尚未反驳它,它似乎验证了我所看到的行为。根据该博客,Connection Lifetime会按预期杀死旧会话,但仅在对数据库进行调用时才会对此参数进行检查。换句话说,长时间运行的空闲会话永远不会被.NET杀死。
  • 如果您将IDLE_TIME设置为Oracle用户配置文件中的值(而不是UNLIMITED),则数据库最终将这些长时间运行的空闲参数设为SNIPED。这最终可能会导致.NET端出现问题,因为除非您明确检查您的连接是否仍处于打开状态,否则.NET将提供这些SNIPED连接,就像它们仍然可用一样(从而抛出上述超时) ORA错误)。
  • 解决此问题的方法是确保连接字符串中包含Data Validation=True;。这可确保.NET在服务连接到下一个服务调用之前检查会话连接。当此验证看到SNIPED会话时,它会将其从.NET连接池中删除。

鉴于此信息,OP的原始问题很可能只是出现在一个站点中,来自不同数据库设置和/或.NET调用数据库的频率。他可能在两种环境中都遇到了问题,但是如果一个环境中的用户经常拨打电话以便Connection Lifetime完成这项工作,那么他就永远不会在该数据库中看到这些超时。

现在我仍然没有想到如何在任何Oracle IDLE_TIME狙击发生之前杀死.NET中的空闲连接,但只要你使用Data Validation = True参数,你就应该可以解决这个问题。

答案 1 :(得分:1)

如果5分钟生命周期设置在第一个站点中运行良好,那么我认为这可能是由某人在Oracle服务器端的配置文件中设置空闲会话超时引起的。

然而,在5分钟的生命周期设置中,当你的突发变得更大时,你可能仍然会超时,因为当你在下一次冲刺中返回到游泳池的连接时,它们会被摧毁。然后,池将忙于创建和删除连接,并且当负载非常大时可能导致连接超时。

答案 2 :(得分:-1)

您可以通过将OracleCommand.ConnectionTimeout属性设置为0来指定无限超时。 在这种情况下,不会超时(至少在客户端)。

在这种情况下也使用ConnectionPool。