自定义数据库连接对象:我应该使用一个通用的(单例)还是每个对象实例一个?

Custom Database Connection Object: Should i use a general one (singleton) or one per object instance?

最佳做法是什么:只创建一个静态 class(单例)来提供所有需要的数据库连接,还是为每个 DAO 实例创建一个对象? 请注意,我的项目同时访问多个数据库,因此我创建了一个 class AcessoBanco 来接收 .INI 配置文件 e returns 我需要的所有连接。 我使用的是单一静态 class 方法,但我收到关于并发的零星异常,因为系统执行一些多线程任务。我通过在 AcessoBanco class 中创建锁来解决它,但是,这真的是个好主意吗? 也许,如果我为每个 dao 对象放置一个 AcessoBanco 实例,并发问题可以更优雅地解决,对吗?一些例子:

使用单例方法

public class Repository1
{
    public Repository1(string iniFilePath)
    {
        AcessoBanco.Configure(iniFilePath); // Singleton that creates all the connections (concurrency excepction solved using locks)

        // After configured, just call AcessoBanco.GetConnections() in any point of the code to get the connections 
    }
}

每个对象使用一个实例

public class Repository2
{
    public AcessoBanco Conexoes { get; set; }
    public Repository2(string iniFilePath)
    {
        Conexoes = new AcessoBanco(iniFilePath); // Using one instance of AcessoBanco in each DAO. I will need to do it in every DAO.
    }
}

这在很大程度上取决于您使用的数据库类型。

仅举两个例子:

  1. CosmosDB - 建议使用客户端的单例实例,因为它使用(最常见的)http 调用,喜欢 HttpClient 单例实例
  2. ADO.NET(对于 sql 服务器)- 使用单例实例是非常糟糕的主意,因为您的应用程序可能想要使用来自不同线程的连接,并且您会 运行一大堆不同的问题。这正是它在后台使用连接池的原因。

您提供的详细信息并不表示使用单例模式是个好主意;相反,正如您已经发现的那样,它可能会导致多线程应用程序出现问题。大多数数据库引擎都支持连接池,opening/closing 连接的开销应该是最小的。也不要提前打开连接。只需在您严格需要的时候打开/关闭连接。你正在制造比你需要的更多的头痛。

像这样或类似的模式没有错:

using (var connection = new Connection()){

}