【问题标题】:ODP.NET connection pooling: How to tell if a connection has been usedODP.NET 连接池:如何判断一个连接是否已被使用
【发布时间】:2011-10-21 06:06:04
【问题描述】:

我正在修改一个 Winforms 应用程序以使用连接池,以便可以在后台线程中进行数据访问。业务逻辑在 PL/SQL 中实现,为了利用业务逻辑,必须调用几个与安全相关的存储过程。

我需要一种方法来判断连接是否已被使用,而无需往返数据库。我不认为我可以在HashSet 中跟踪它们,因为我怀疑Equals 甚至ReferenceEquals 是否可靠。有什么想法吗?

编辑:

为了清楚起见,我打算使用 ODP.NET 的内置连接池机制。如果我滚动自己的连接池,跟踪哪些连接是新的还是使用的将非常简单。

【问题讨论】:

  • 走“极其微不足道”的路线..你为什么要做其他事情?
  • 我的意思是,您不想重新发明轮子,但要明确表示您想重新发明轮子。 :) [或者,轮子的一部分]。
  • 我不是很清楚吗?我不想重新发明 连接池 轮子。我只想知道是否已经建立了连接以节省时间做一些每个连接的业务逻辑 API 初始化代码。

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


【解决方案1】:

ODP.NET 提供的连接池是完全不透明的。也就是说,它不会像我希望的那样泄漏——无法知道连接是以前使用过的还是全新的。然而,它是另一种泄漏的抽象:任何会话状态(例如,包范围的变量,它们是会话范围的)在连接的使用之间被保留。由于这是一个关于无需访问数据库来确定连接的已用状态还是新状态的问题,因此答案是使用 ODP.NET 的内置连接池根本无法完成。 p>

剩下两个选择:

  1. 创建一个连接池实现,它要么提供该信息,要么在创建每个新连接时执行用户定义的初始化;或
  2. 执行到数据库的往返以确定连接的已使用状态和新状态。

【讨论】:

  • 为了记录,我构建了一个通用对象池,它将对象创建外包给注入其中的工厂。我回收了已经包含设置代码的现有 Oracle 连接工厂。效果很好。
  • 2 个其他选择:确保您的连接始终处于已知状态(您可以利用using 加上IDisposables 撤消对您所做的连接的任何更改。)或者,如果您的情况允许,只需无条件地重做任何设置操作。
【解决方案2】:

ADO.NET 为您管理一个连接池。它甚至是可配置的。为什么您会尝试自己跟踪这些联系?

http://msdn.microsoft.com/en-us/library/bb399543.aspx

而且,专门针对 Oracle:

http://msdn.microsoft.com/en-us/library/ms254502.aspx

Oracle 的 .NET Framework 数据提供程序提供连接 为您的 ADO.NET 客户端应用程序自动进行池化。你可以 还提供几个连接字符串修饰符来控制连接 池行为(请参阅“使用连接控制连接池 字符串关键字,”本主题后面)。

池创建和分配

当一个连接被打开时,一个连接池是基于一个 将池与连接相关联的精确匹配算法 连接中的字符串。每个连接池都关联一个 不同的连接字符串。打开新连接时,如果 连接字符串与现有池不完全匹配,新的 池已创建。

一旦创建,连接池在激活之前不会被销毁 过程结束。维护非活动或空池使用很少的系统 资源。

顺便说一句,我想我并不完全赞同 OracleClient 正在进行的所有更改。似乎微软可能会放弃支持?最后我知道 ODP.NET 是基于 ADO.NET 的......但是,即使我弄错了,ODB.NET 也声称支持开箱即用的连接池:

http://download.oracle.com/docs/html/E10927_01/featConnecting.htm#CJAFIDDC

【讨论】:

  • 是的,我打算使用ODP.NET提供的内置连接池。否则(如果我自己动手)我会确切地知道我何时创建新连接而不是抛出一个已经初始化的连接。
  • 我认为史蒂夫要问的问题是,当提供商 (ODP.NET) 已经处理好连接池中的连接时,手动跟踪连接有什么好处?因此,您只需要继续使用您的业务逻辑和其他代码,并且池在后台是透明的。
  • 它不是透明的,它是不透明的。如果它是透明的,我实际上可以看到以前是否使用过连接。
  • 它有什么区别,因为您无法控制要从池中取出的连接?
  • 如果您依赖于根据之前是否使用过来确定连接的状态(经过身份验证/未经身份验证),我认为您真的让自己陷入了痛苦的境地。
【解决方案3】:

如果您只需要知道您是否曾经有一些连接不是来自池而是一个新的连接,我认为您可以使用 ODP.NET 提供的 HardConnectsPerSecond 和 SoftconnectsPerSecond 性能计数器。

不过,这不会告诉您究竟是哪个 OracleConnection.Open() 导致了硬连接。我也在考虑结合其他 ODP.NET 性能计数器来确定是否创建了新的硬连接,但是经过一些实验后这并不容易,因为 ODP.NET 还会每三分钟清除一次连接(取决于 Decr 池大小设置) .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-23
    • 2010-10-14
    • 2013-12-31
    • 1970-01-01
    • 2012-05-01
    • 2012-04-18
    • 1970-01-01
    相关资源
    最近更新 更多