首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么不推荐使用一个公共OleDbConnection?解决bug的替代方案:打开的连接太多

为什么不推荐使用一个公共OleDbConnection?解决bug的替代方案:打开的连接太多
EN

Stack Overflow用户
提问于 2011-06-16 01:44:52
回答 2查看 2.3K关注 0票数 6

我必须与另一个开发人员的项目工作。一个项目的Win与Visual-Basic代码,MS-Access作为数据库和一些OleDbConnections。有一个错误:有时应用程序无法打开OleDbConnection,因为数据库已达到最大连接数。我知道使用连接的最好方法是:

代码语言:javascript
复制
Using cn As New OleDbConnction(s)
  ...
  cn.Close()
End Using

但是在这个项目中,有许多使用数据库的类,并且在这些类中有许多具有"Friend“可见性的OleDbConnections,它们在不同的时间打开和关闭。由于这个原因,不可能将所有的OleDbConnections都放在一个Using构造中,并且很难找到关闭其中一个OleDbConnection时“忘记”了什么操作。

一种可能的解决方案是只使用一个唯一的公共OleDbConnection,并在打开它之前检查它是否还没有打开。但有人告诉我,这是一种非常糟糕的做法。我想他跟我说过关于演出的事,但我不是很清楚。你能告诉我为什么一个唯一的公共OleDbConnection如此被弃用吗?对我来说,你有没有一个简单的方法来解决我的问题?谢谢,Pileggi

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-16 12:28:56

从您的描述中,我看到了几个可能导致您的问题的问题:

  • 嵌套连接:

您在each-other

  • open/release连接中打开多个连接的速度太快:

正如David-W-Fenton提到的,使用access,每次打开/关闭单个连接时,都会创建/删除锁文件。此操作相当慢,如果您在应用程序中快速打开/关闭数据库(执行大量原子查询),则可能会出现此问题。

调查和解决该问题的几种可能方法:

跟踪所有打开/关闭调用

添加一些调试跟踪,这些跟踪在每次打开和关闭连接时显示。

它将允许您检测嵌套连接以及您的连接池被浪费的位置。

强制连接轮询一个简单的“修复”方法可能是在您的连接字符串中明确设置连接池。它应该是默认的行为,所以也许它不会解决你的问题,但它是如此简单,没有理由不尝试它:

代码语言:javascript
复制
OLE DB Services=-1

使用连接管理器类为您创建/释放连接。

用您自己的代码替换所有显式创建的新OleDbConnection和close操作。这将允许您在整个应用程序中始终重用单个现有连接,并允许您通过将行为集中在一个位置来快速调整整个应用程序。

:为什么通常不推荐使用单个连接呢?

  • 通常,您不应该在整个应用程序中保持打开的连接,因为它们会强制数据库服务器为您保留可用的资源,并且会减少可以连接的客户端的数量(可用连接的数量始终是有限的)。

但是,对于没有服务器部分的基于-a文件的数据库的访问,保持单个连接打开实际上更可取,因为与打开新连接相关的延迟(创建锁文件)。由于访问并不意味着要与大量并发用户一起使用,因此保持连接打开的资源成本不足以成为问题。

  • From simple tests OleDb驱动程序会为你做连接池,所以当它们被释放时,它能够重用连接。

  • 通过保持你的连接和数据库操作的小和包含,你在使用线程时不太可能遇到并发问题。如果您使用相同的数据库管道执行多个操作,则保持全局连接可能会成为一个问题。
票数 6
EN

Stack Overflow用户

发布于 2014-08-08 14:10:44

只是添加了一些对我有效多年的信息(这有点类似于David-W-Fenton suggests)

首先,微软Access (MDB,JET)的OleDbConnection没有使用连接池。作为Microsoft states in KB191572

使用Jet OLE DB提供程序和ODBC驱动程序的

连接不会被池化,因为这些提供程序和驱动程序不支持池化。

关于连接池,也有this blog post from Ivan Mitev声明:

那么这是什么意思呢?很明显,主动打开的连接的存在使得关闭和打开多个连接的测试完成得更快(2-3倍)。对我来说,唯一可能的解释是,每次没有活动连接时,连接池都会被释放。我必须做进一步的调查,并在Microsoft数据访问组件中阅读类似池化的内容。或者,为了保持池的活动状态,可能只保留一个打开的连接。这将是丑陋的,但它仍然是一个足够好的解决办法!如果有人有更好的想法,请分享。

和Microsoft notes in MSDN

ADO Connection对象隐式使用IDataInitialize。但是,这意味着您的应用程序需要始终为每个唯一用户保留至少一个实例化的Connection对象实例。否则,当该字符串的最后一个连接对象关闭时,池将被销毁。

基于所有这些和我自己的测试,my solution使用Microsoft Access数据库来“模拟”连接池,大致遵循以下步骤:

  1. 在应用程序中尽可能早地打开一个OleDbConnection到Access数据库中,尽可能早地处理OleDbConnection,就像在应用程序生命周期中尽可能晚地打开一个总是打开的OleDbConnection一样。

这极大地提高了我的应用程序(主要是WinForms)的速度。

请注意,这也适用于Sqlite,它似乎也不支持连接池。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6361947

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档