【问题标题】:Multithreading and database connection(s)多线程和数据库连接
【发布时间】:2010-02-22 15:39:29
【问题描述】:

所以我试图找出我的数据库连接的最佳做法。我有一个大型 .NET GUI 作为 MySQL 数据库的前端。目前,我在应用程序加载时打开一个连接,并将其用于我需要的任何交互。但是,整个 GUI 是单线程的。

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

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

有哪些常见的设计模式?

谢谢-

乔纳森

【问题讨论】:

    标签: .net mysql design-patterns


    【解决方案1】:

    使用线程安全的连接池并保持线程特定的连接(不要跨线程共享连接)。

    我相信 MySQL .NET 连接框架是内置的。如果您对所有连接使用相同的连接字符串,只需将“pooling=true”添加到您的连接字符串。 (Source -- 没有超链接片段,所以在表中寻找“pooling”)

    这种方法的缺点是一些线程会阻塞,直到连接可用。您需要在程序结构中考虑到这一点。

    【讨论】:

      【解决方案2】:

      有两种方式:

      1. 单连接——在这种情况下,连接被创建1次,并在所有请求中分配,如果大量同时请求导致生产力损失,你必须自己控制线程节省。

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

      您需要分析和预测应用程序的行为并选择适当的路径。如果您有一个简单的应用程序,您可能不需要使用池。如果应用程序需要高负载和未来可扩展性,那么使用池是正确的。

      【讨论】:

        【解决方案3】:

        通过一个打开的连接,您应该拥有与数据库的最大吞吐量。但是,您最终会在应用程序中编写复杂的代码来共享连接。

        Here 是一篇关于资源共享模式的文章。示例在 Ada 中,但我相信您仍然可以阅读。

        【讨论】:

          【解决方案4】:

          连接到数据源可能很耗时。为了最大限度地降低打开连接的成本,ADO.NET 使用了一种称为连接池的优化技术,该技术将重复打开和关闭连接的成本降至最低。对于 .NET Framework 数据提供程序,连接池的处理方式不同。

          来自 MSDN。

          看这里Connection Pooling (ADO.NET)

          【讨论】:

            【解决方案5】:

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

            显然,从带有 SQL Server 的 .NET(从未尝试使用 MySQL)来看,这两种方法都没有明显的性能损失(这不足为奇,因为在 ConnectAndDisconnectEachTime 场景中,较低层并没有真正立即断开连接)。 但是有一个细微的差别让我们决定使用 ConnectionAlwaysOpen。原因是事务支持。 如果您打算使用事务,那么连接/断开连接将不起作用,我认为这显然是为什么。

            ConnectionAlwaysOpen 当然可以使用现有的连接池或连接池的一些手动惰性缓存来改进,但基本思想保持不变。另一方面,在 Web 应用程序中,这种方法的实现和线程安全有点困难,但值得付出努力。

            【讨论】:

            • 当您说 ConnectAndDisconnect 方案无法支持事务时,您是在谈论支持自应用程序启动以来回滚所有内容的“全局”事务?如果没有,即使使用 ConnectAndDisconnect,您也可以获得事务支持。您必须组织代码以识别“高级”事务,然后在 C# (msdn.microsoft.com/en-us/library/…) 中使用例如“TransactionScope”
            • @FrenchData 我正在谈论来自业务逻辑层的中间层事务。我们尝试了 TransactionScope 方法,但还不够,我们很快遇到了麻烦,因为中间层代码以不同的不可预见的方式使用。解决方案在某种程度上是这两种方法的混合体,我们的 ConnectionManager 类支持这两种方法。当然,从应用开始就不需要交易,这就是混合解决方案更好的原因。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-05-06
            • 2015-04-03
            • 1970-01-01
            • 1970-01-01
            • 2018-08-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多