2010-02-22 96 views
11

所以我想弄清楚我的数据库连接的最佳实践。我有一个大的.NET GUI作为MySQL数据库的前端。目前,我在应用程序加载时打开一个连接,并将其用于我需要的任何交互。但是,整个GUI是单线程的。多线程和数据库连接

当我开始为大型查询添加BackgroundWorkers并执行时,我很担心我的打开连接。例如,我知道我一次只能在该连接上打开一个dataReader。有了多个线程,用户可以尝试实例化更多。

为应用程序保持一个打开的连接与为每个交互打开一个新的连接有什么优点/缺点?

这是什么常见的设计模式?

Thanks-

乔纳森

回答

6

使用一个线程安全的连接池,并保持连接线程特定(不要在线程之间共享连接)。

我相信MySQL .NET连接框架附带内置的一个。如果对所有连接使用相同的连接字符串,只需在连接字符串中添加“pooling = true”即可。 (Source - 没有超链接片段,因此请在表格中查找“池”)

此方法的缺点是某些线程会阻塞,直到连接可用。您需要在程序结构中对此进行解释。

1

对于一个打开的连接,您应该对数据库具有最大的吞吐量。然而,你最终在应用程序中编写复杂的代码来共享连接。

Here是关于资源共享模式的文章。这些例子都在Ada中,但我相信你仍然可以阅读它。

1

连接到数据源可能非常耗时。为了最小化开放连接的成本,ADO.NET使用称为连接池的优化技术,该技术可以最大限度地降低反复打开和关闭连接的成本。 .NET Framework数据提供者对连接池的处理方式不同。

来自MSDN。

看到这里Connection Pooling (ADO.NET)

3

有2种方式:

  1. 单连接 - 在这种情况下,连接创建1次,所有的请求之间分配,如果有大量的并发请求导致生产力损失,并且您必须控制自己保存线程。

  2. 每个请求的连接 - 在这种情况下,您必须在执行请求后立即打开连接并立即关闭连接。但同时打开的连接数量可能受到服务器的限制。在这里,创建连接的开销始终存在,但是使用线程安全连接池解决,这是很好的做法。

您需要分析和预测应用程序的行为并选择适当的路径。如果你有一个简单的应用程序,你可能不需要使用这个池。如果应用程序需要严重的负载和未来的可伸缩性,则使用这些池是正确的。

0

在决定走哪条路之前,我们已经做了一些测试。我的意思是在ConnectionAlwaysOpen或ConnectAndDisconnectEachTime之间。

显然从使用SQL Server的.NET(从来没有用MySQL试过),在任何一种方法中都没有可见的性能损失(毫无意外,因为低层不会立即在ConnectAndDisconnectEachTime方案中立即断开连接)。 但有一个细微的差异,使我们决定为ConnectionAlwaysOpen。原因是交易支持。 如果你打算使用交易,那么连接/断开连接将不起作用,我想这显然是为什么。

当然ConnectionAlwaysOpen可以使用现有的连接池或连接池的一些手动懒惰高速缓存来改善,但基本思路保持不变。在另一方面,在Web应用程序中这是一个有点难以实现,线程安全的这种做法,但它可能值得。

+0

当你说的事务支持是不可能的ConnectAndDisconnect情况下,你说的是一个“全球性”的交易,因为应用程序的启动,将支持回滚一切吗?如果没有,即使使用ConnectAndDisconnect,您也可以获得事务支持。你必须安排,以便确定“高层次”的事务,然后使用例如“TransactionScope的”在C#代码(http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx) – FrenchData 2010-02-23 10:50:56

+0

@法国数据 我被描述为来自业务逻辑层的中层交易。我们已经尝试了TransactionScope的方法,但它是不够的,我们很快就遇到了麻烦,因为中间层的代码在不同的不可预见的方式使用。解决方案在某种程度上是两种方法的混合体,我们的ConnectionManager类支持这两种方法。 当然,从应用程序开始就不需要交易,这就是为什么混合解决方案更好。 – AureliusMarcus 2010-02-24 11:30:46