ODP.NET 连接池:如何判断连接是否已被使用
我正在修改 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
ODP.NET 提供的连接池是完全不透明的。也就是说,它并没有像我希望的那样泄漏 - 无法知道连接是否以前使用过或者是全新的。然而,从另一种角度来看,它是一个有漏洞的抽象:任何会话状态(例如,包作用域的变量,它们是会话作用域的)都在连接的使用之间保留。由于这是一个关于在不访问数据库的情况下确定连接的已用状态与新状态的问题,答案是使用 ODP.NET 的内置连接池根本无法完成此操作。
这留下了两个选择:
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:
ADO.NET 为您管理连接池。它甚至是可配置的。您为什么要尝试自己追踪这些联系?
http://msdn.microsoft.com/en-us/library/bb399543.aspx
并且,专门针对 Oracle:
http://msdn.microsoft.com/en-us/library/ms254502.aspx
顺便说一句,我想我对 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
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
如果您需要的只是知道是否曾经有过一些连接不是来自池而是来自新的连接,我认为您可以使用 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).