自定义数据库连接对象:我应该使用一个通用的(单例)还是每个对象实例一个?
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.
}
}
这在很大程度上取决于您使用的数据库类型。
仅举两个例子:
CosmosDB
- 建议使用客户端的单例实例,因为它使用(最常见的)http 调用,喜欢 HttpClient
单例实例
ADO.NET
(对于 sql 服务器)- 使用单例实例是非常糟糕的主意,因为您的应用程序可能想要使用来自不同线程的连接,并且您会 运行一大堆不同的问题。这正是它在后台使用连接池的原因。
您提供的详细信息并不表示使用单例模式是个好主意;相反,正如您已经发现的那样,它可能会导致多线程应用程序出现问题。大多数数据库引擎都支持连接池,opening/closing 连接的开销应该是最小的。也不要提前打开连接。只需在您严格需要的时候打开/关闭连接。你正在制造比你需要的更多的头痛。
像这样或类似的模式没有错:
using (var connection = new Connection()){
}
最佳做法是什么:只创建一个静态 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.
}
}
这在很大程度上取决于您使用的数据库类型。
仅举两个例子:
CosmosDB
- 建议使用客户端的单例实例,因为它使用(最常见的)http 调用,喜欢HttpClient
单例实例ADO.NET
(对于 sql 服务器)- 使用单例实例是非常糟糕的主意,因为您的应用程序可能想要使用来自不同线程的连接,并且您会 运行一大堆不同的问题。这正是它在后台使用连接池的原因。
您提供的详细信息并不表示使用单例模式是个好主意;相反,正如您已经发现的那样,它可能会导致多线程应用程序出现问题。大多数数据库引擎都支持连接池,opening/closing 连接的开销应该是最小的。也不要提前打开连接。只需在您严格需要的时候打开/关闭连接。你正在制造比你需要的更多的头痛。
像这样或类似的模式没有错:
using (var connection = new Connection()){
}