在 ASP.NET 网站中使用单例进行连接是一个好主意吗
我目前在我的 Web 应用程序上使用单例,以便始终只有一个与数据库的连接。
我想知道这是否是一个好主意,因为现在我遇到了这个错误:
超时已过期。从池中获取连接之前超时时间已过。发生这种情况可能是因为所有池连接都在使用中并且达到了最大池大小。
另一个重要的一点是,我的网站目前处于开发阶段,没有很多人继续使用它,所以我不明白为什么我得到这个错误!
这是我的单身人士的代码:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
/// <summary>
/// This class take care of all the interaction with the database
/// </summary>
public class DatabaseFacade
{
SqlConnection m_conn = null;
string m_csLanguageColumn;
//Variables that implement the Singleton pattern
//Singleton pattern create only one instance of the class
static DatabaseFacade instance = null;
static readonly object padlock = new object();
/// <summary>
/// Private constructor. We must use Instance to use this class
/// </summary>
private DatabaseFacade()
{
}
/// <summary>
/// Static method to implement the Singleton
/// </summary>
public static DatabaseFacade Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new DatabaseFacade();
}
return instance;
}
}
}
/// <summary>
/// Do the connection to the database
/// </summary>
public void InitConnection(int nLanguage)
{
m_conn = new SqlConnection(GetGoodConnectionString());
try
{
//We check if the connection is not already open
if (m_conn.State != ConnectionState.Open)
{
m_conn.Open();
}
m_csLanguageColumn = Tools.GetTranslationColumn(nLanguage);
}
catch (Exception err)
{
throw err;
}
}
}
感谢您的帮助!
I'm currently using a singleton on my web application so that there is always only one connection to the database.
I want to know if it's a good idea because right now I'm having trouble with that error:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Another important point is that my website is currently in dev and not a lot of people go on it so I don't understand why I get this error!
Here is the code of my singleton:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
/// <summary>
/// This class take care of all the interaction with the database
/// </summary>
public class DatabaseFacade
{
SqlConnection m_conn = null;
string m_csLanguageColumn;
//Variables that implement the Singleton pattern
//Singleton pattern create only one instance of the class
static DatabaseFacade instance = null;
static readonly object padlock = new object();
/// <summary>
/// Private constructor. We must use Instance to use this class
/// </summary>
private DatabaseFacade()
{
}
/// <summary>
/// Static method to implement the Singleton
/// </summary>
public static DatabaseFacade Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new DatabaseFacade();
}
return instance;
}
}
}
/// <summary>
/// Do the connection to the database
/// </summary>
public void InitConnection(int nLanguage)
{
m_conn = new SqlConnection(GetGoodConnectionString());
try
{
//We check if the connection is not already open
if (m_conn.State != ConnectionState.Open)
{
m_conn.Open();
}
m_csLanguageColumn = Tools.GetTranslationColumn(nLanguage);
}
catch (Exception err)
{
throw err;
}
}
}
Thanks for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用单个连接是一个极其糟糕的主意 - 如果对连接的访问被正确锁定,则意味着 ASP.NET 一次只能为一个用户提供服务,这将严重限制您的应用程序的增长能力。
如果连接未正确锁定,事情就会变得非常奇怪。例如,一个线程可能会释放连接,而另一个线程则尝试针对该连接执行命令。
您应该在需要时创建新的连接对象,而不是使用单个连接,以利用连接池。
连接池是SqlClient 类的默认行为(可能还有其他数据)提供商)。当您使用连接池时,每当您“创建”连接时,该连接实际上都会从现有连接池中拉出,这样您就不会每次都从头开始构建一个连接。当您释放它(关闭它或处置它)时,您将其返回到连接池,从而使连接总数保持相对较低。
编辑:如果您不关闭(或处置)连接,您将看到您提到的错误(从池中获取连接之前超时时间已过)。确保在使用完每个连接后立即执行此操作。
有几个很好的堆栈溢出问题讨论了这个问题,我怀疑这可能会有所帮助!
处置/关闭?
SQL 连接在以下情况下关闭
抛出异常?
Using a single connection is an extremely bad idea - if access to the connection is properly locked, it means that ASP.NET can only serve one user at a time, which will seriously limit your application's ability to grow.
If the connection is not properly locked, things can get really weird. For example, one thread might dispose the connection while another thread is trying to execute a command against it.
Instead of using a single connection, you should just create new connection objects when you need them, to take advantage of connection pooling.
Connection pooling is the default behavior for the SqlClient classes (and probably other data providers). When you use connection pooling, any time you 'create' a connection, the connection will actually be pulled from a pool of existing ones so that you don't incur the costs of building one from scratch each time. When you release it (close it or dispose of it) you return it to the connection pool, keeping your total count of connections relatively low.
Edit: You'll see the error you mention (The timeout period elapsed prior to obtaining a connection from the pool) if you're not closing (or disposing) your connections. Make sure you do that as soon as you're done using each connection.
There are several good stack overflow questions that discuss this, which I suspect might be helpful!
disposed/closed?
SQL connection is closed when an
exception is thrown?
不,这是一个坏主意。您使用连接池。
No, it's a bad idea. You use connection pooling.
使用数据库的连接作为单例是一个可怕的想法,因为每个第二个以上的连接都必须等待第一个连接被释放。
单例意味着只有一个数据库连接对象来连接到数据库。因此,如果第二个人想要连接到它,他们需要等待,直到他们可以访问该对象。
这是个坏消息。
只需在需要时继续创建数据库连接对象的新实例即可。这里的技巧是尽可能晚地打开连接,然后尽快关闭该连接。
数据库连接对象中最昂贵的操作是实际的连接。不是创造。
The reason why using a Connection to the database as a singleton is an horrific idea, is because every 2nd+ connection will then have to WAIT for the first connection to be released.
A singleton means that there's only one database connection object, to connect to the db. So if a second person wants to connect to it, they need to wait until they can access that object.
That's bad news.
Just keep creating new instances of the database connection object, when required. The trick here is to open the connection as late as possible and then close that connection as soon as possible.
The most expensive operation in a database connection object, is the actual connection. not the creation.
不需要单例。以下是一些有关连接池的文章:
.NET 1.1
SQL Server .NET Framework 数据提供程序的连接池
.NET 2.0
在 SQL Server 中使用连接池
.NET 3.0
使用连接池
.NET 3.5
SQL Server 连接池 (ADO.NET)
.NET 4.0
SQL Server 连接池 (ADO.NET)
No need for a Singleton. Here are some articles on connection pooling:
.NET 1.1
Connection Pooling for the .NET Framework Data Provider for SQL Server
.NET 2.0
Using Connection Pooling with SQL Server
.NET 3.0
Using Connection Pooling
.NET 3.5
SQL Server Connection Pooling (ADO.NET)
.NET 4.0
SQL Server Connection Pooling (ADO.NET)