ODP.NET 连接池:如何判断连接是否已被使用

发布于 2024-12-10 20:40:32 字数 346 浏览 0 评论 0原文

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

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

编辑:

需要明确的是,我计划使用 ODP.NET 的内置连接池机制。如果我推出自己的连接池,那么跟踪哪些连接是新的、哪些是已使用的将非常简单。

I'm modifying a Winforms app to use connection pooling so data access can occur in background threads. The business logic is implemented in PL/SQL and there are a couple of security related stored procedures that have to be called in order to make use of the business logic.

What I need is a way to tell if the connection has been used without a round-trip to the database. I don't think I can keep track of them in a HashSet because I doubt Equals or even ReferenceEquals could be relied upon. Any ideas?

EDIT:

Just to be clear, I plan to use ODP.NET's built-in connection pooling mechanism. If I rolled my own connection pool, keeping track of which connections were new vs. used would be extremely trivial.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏雨凉 2024-12-17 20:40:32

ODP.NET 提供的连接池是完全不透明的。也就是说,它并没有像我希望的那样泄漏 - 无法知道连接是否以前使用过或者是全新的。然而,从另一种角度来看,它是一个有漏洞的抽象:任何会话状态(例如,包作用域的变量,它们是会话作用域的)都在连接的使用之间保留。由于这是一个关于在不访问数据库的情况下确定连接的已用状态与新状态的问题,答案是使用 ODP.NET 的内置连接池根本无法完成此操作。

这留下了两个选择:

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

The connection pooling provided by ODP.NET is completely opaque. That is, it isn't leaky in the way I'd like it to be - there is no way of knowing if a connection has been used before or is brand new. However it is a leaky abstraction in another way: Any session state (e.g. package scoped variables, which are session scoped) is preserved between usages of the connection. Since this is a question about determining the used vs. new state of a connection without going to the database, the answer is that it simply cannot be done using ODP.NET's built-in connection pool.

That leaves two options:

  1. Create a connection pool implementation that either provides that information or performs user-defined initialisation upon creation of each new connection; or
  2. Perform a round-trip to the database to determine the used vs. new state of the connection.
你在我安 2024-12-17 20:40:32

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

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

并且,专门针对 Oracle:

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

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

池创建和分配

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

连接池一旦创建,就不会被销毁,直到活动为止
过程结束。维护不活动或空的池使用很少的系统
资源。

顺便说一句,我想我对 OracleClient 正在发生的所有变化并不完全感兴趣。看来微软可能会放弃支持?最后我知道 ODP.NET 是基于 ADO.NET...但是,即使我弄错了,ODB.NET 也声称支持开箱即用的连接池:

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

ADO.NET manages a connection pool for you. It's even configurable. Why would you ever try to track these connections yourself?

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

And, specifically for Oracle:

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

The .NET Framework Data Provider for Oracle provides connection
pooling automatically for your ADO.NET client application. You can
also supply several connection string modifiers to control connection
pooling behavior (see "Controlling Connection Pooling with Connection
String Keywords," later in this topic).

Pool Creation and Assignment

When a connection is opened, a connection pool is created based on an
exact matching algorithm that associates the pool with the connection
string in the connection. Each connection pool is associated with a
distinct connection string. When a new connection is opened, if the
connection string is not an exact match to an existing pool, a new
pool is created.

Once created, connection pools are not destroyed until the active
process ends. Maintaining inactive or empty pools uses very few system
resources.

BTW, I guess I'm not totally hip on all the OracleClient changes that have been going on. It seems like Microsoft may be dropping support? Last I knew ODP.NET was based on ADO.NET... but, even if I'm mistaken about that, ODB.NET claims to support connection pooling out of the box as well:

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

风吹雪碎 2024-12-17 20:40:32

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

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

If what you need is to just know whether you ever had some connections not come from pool but a fresh new one, I think that you can use the HardConnectsPerSecond and SoftconnectsPerSecond performance counter provided by ODP.NET.

This won't tell you exactly which OracleConnection.Open() leads to a hard connection, though. I was also thinking about combining other ODP.NET perf counter to determine if a new hard connection is created, but after some experiments this is not easy because ODP.NET will also purge connections every three minutes (depending on the Decr Pool Size setting).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文