使用单例模式在数据访问层中的优缺点

4

我希望使用单例模式实现DAL,但我认为连接池、事务等方面比较困难。

我想了解其优缺点,并想知道连接池的最佳方法,因为我正在开发的网站可能会有500多个并发用户。

数据库服务器是Oracle 10g。

DAL使用Enterprise Library 3.1。

6个回答

3
单例模式非常适合用于数据访问层(DAL) - 我在自己的企业Web应用程序中使用了它(有数百个用户和20多个单例类中的2000多种方法)。连接池确实最好由ado.net和sql server本身处理。如果您想要多种类型的后端服务器,这不是问题。即使使用单例模式,您也可能需要一个集中的数据访问类,该类处理实际进行直接调用数据库的具体细节(传入参数、文本/过程名称、凭据/连接字符串等)。
在我的情况下,每个单例上的每个方法与我的数据库中的一个存储过程对应。这基本上为每个存储过程创建了一个C#“前端”挂钩,以便它们可以像本机C#代码一样被调用,从语法上讲。它使对DAL的调用非常简单。我有多个单例,因为涉及到大量的存储过程。每个存储过程都有一个前缀,例如Development_,Financial_,Organization_或其他。然后,我有一个对应于每个前缀的单例类,例如Development、Financial或Organization。因此,在C#中,sp Organization_ViewData将成为名为ViewData的方法的单例类命名为Organization。
当然,这只是一种方法,但我发现在过去的六年中,它在多个开发人员和大量代码的情况下非常有效。关键是一致性。如果前端程序员查看单例代理中方法的名称,那么这应该告诉他们它正在进入数据库端的确切位置。这样,如果出现问题,或者某人必须搜索代码以尝试理解它,就需要进行更少的跟踪。

1

连接池最佳实践是不要自己实现,而是让 ADO.NET 框架来处理它。

您可以将连接池选项设置为连接字符串中的参数。然后,使用该字符串打开的每个连接都将从由框架实现和管理的连接池中提供。当您关闭或处理 OracleConnection 时,底层连接不会被销毁,而是会回到池中。

这在此处进行了描述: http://msdn.microsoft.com/en-us/library/ms254502.aspx

关于单例的使用:我已经用它们包装了数据访问层,并且一直运行良好。

请注意,事务仅适用于特定连接,而不是整个数据库。这意味着您可以运行多个线程,并且每个线程都可以通过独立事务读写数据库,只要每个线程使用单独的 OracleConnection 实例即可。


我已经添加了另一段来谈论事务处理。 - Andrew Shepherd
但是,如果我们有一个单一的DAL对象被多个应用程序共享,那么我们如何使用ADO.net的连接池呢?因为这个单一的DAL对象每次只需要一个连接。 - Novice
很可能,来自不同应用程序的每个调用都将在不同的线程上进行。只会有一个DAL对象,但框架将同时在单独的线程上调用方法。每个线程都需要自己的连接。 - Andrew Shepherd

0

我不知道DAL是什么,但单例模式是一种很好的方法,可以使数据全局化,同时保持良好的封装性。


0

在数据访问层(DAL)中使用单例模式作为数据库连接工厂是相当常见的。它使您更轻松地插入不同的工厂实现,而无需改变大量代码。很多人似乎不喜欢单例模式,但我认为它对于这种类型的事情还是可以的。


0

我认为使用单例模式与否不会影响性能,因为您仍然可以在同一时间内运行多个线程。如果您注意不在所有线程中共享内部字段,那么一切都将正常工作。

最终,管理连接池的类需要是线程安全的,您最终会进行一些锁定,这可能会影响性能,但它们都是必需的。(它在框架内部制作,您无法改变其行为)

如果您决定不使用单例,请确保您的DAL实例很轻量级,因为这可能会有所不同,但通常不会。

注意:谈到连接池时,您必须注意遵循“尽可能晚地打开,尽早关闭”的模式。也就是说,在尽可能长的时间内延迟连接的打开,并在完成所有操作后尽快关闭它。

在使用此魔术规则构建整个系统之后,您可以尝试更改连接字符串参数以更改某些池选项(初始大小,最大大小等)


0

在使用单例模式处理数据访问层时,我有些不安。如果我想要使用多个数据库后端怎么办?也许我想在发票中使用MsSQL,但在身份验证中使用Active Directory。或者我想在论坛帖子中使用MySQL,但在地理聚类方面使用PostgreSQL(对我来说更现实,呵呵)。当我无法将模拟数据库连接传递给测试时,单例接口可能会使测试数据库层变得更加具有挑战性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接