我想我需要一种替代方法来打开和关闭数据库连接,因为我收到一个锁定IIS6的错误。谢谢你的帮助。
根据我的阅读,我需要IDispose
方法从XML进行db更新
我收到此错误消息:
StackTrace:at System.Data.ProviderBase.DbConnectionInternal.PrePush(对象 expectedOwner)
在System.Data.ProviderBase.DbConnectionPool.PutObject(DbConnectionInternal obj,Object owningObject)
在System.Data.ProviderBase.DbConnectionInternal.CloseConnection(DbConnection owningObject,DbConnectionFactory connectionFactory)
在System.Data.SqlClient.SqlInternalConnection.CloseConnection(DbConnection owningObject,DbConnectionFactory connectionFactory)
在System.Data.SqlClient.SqlConnection.Close()
在ASP.chat7_handlers_broadcasting_handler_aspx.XML.Finalize()中 g:\ blah.handler.aspx:第73行
代码:
<%@ Page language="c#" %>
<%@ Import namespace="System.Net"%>
<%@ Import namespace="System.Data"%>
<%@ Import namespace="System.Data.SqlClient"%>
<%@ Import namespace="System.IO"%>
<%@ Import namespace="System.Xml"%>
<script runat="server" language="C#">
public class XML
{
SqlConnection dbConn;
public XML()
{
dbConn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
dbConn.Open();
}
public void add2Db(string table, string sqlRows, string sqlValues)
{
string sql = "INSERT INTO " + table + " (" + sqlRows + ") VALUES (" + sqlValues + ")";
SqlCommand cmd = new SqlCommand(sql, dbConn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
public void parseXML(XmlDocument doc)
{
string tsLogpro = "";
string sqlRows = "";
string sqlValues = "";
//SELECT NODE: logPro
foreach (XmlNode logPro in doc.SelectNodes("logPro"))
{
tsLogpro = logPro.SelectSingleNode("@ts").InnerText;
//SELECT CHILD NODE: logPro
foreach (XmlNode child in logPro.ChildNodes)
{
//SELECT ALL CHILD NODES
foreach (XmlNode node in logPro.SelectNodes(child.Name))
{
//GET ROWS
foreach (XmlNode rows in child.Attributes)
{
sqlRows += rows.Name + ", ";
}
foreach (XmlNode nodeChild in node)
{
sqlRows += nodeChild.Name + ", ";
}
//GET VALUES
foreach (XmlNode values in child.Attributes)
{
sqlValues += "'" + values.InnerText + "', ";
}
foreach (XmlNode nodeChild in node)
{
sqlValues += "'" + nodeChild.InnerText + "', ";
}
sqlRows = "action, " + sqlRows;
sqlRows = sqlRows.Substring(0, sqlRows.Length - 2);
sqlValues = "'" + child.Name + "', " + sqlValues;
sqlValues = sqlValues.Substring(0, sqlValues.Length - 2);
//Response.Write("\n\n");
//Response.Write(sqlRows);
//Response.Write("\n" + sqlValues);
add2Db("fchat7_logpro", sqlRows, sqlValues);
}
sqlValues = "";
sqlRows = "";
}
}
}
~XML()
{
dbConn.Close();
}
}
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
Response.ExpiresAbsolute = DateTime.Now;
Response.AddHeader("Content-type", "text/plain");
HttpRequest request = HttpContext.Current.Request;
System.IO.Stream body = request.InputStream;
System.Text.Encoding encoding = request.ContentEncoding;
System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
XmlDocument doc = new XmlDocument();
string s = reader.ReadToEnd();
if (Request.Params["action"] != string.Empty && Request.Params["action"] == "test")
{
doc.InnerXml = "" +
"<logPro ts=\"1283351509\">" +
"<autoLogin uid=\"d5b0ef4c8c51f303ecbaed81a6e078c5\" hasCam=\"false\" ip=\"127.0.0.1\" ts=\"1283351406\" />" +
"<chatLogin hasCam=\"false\" ip=\"127.0.0.1\" ts=\"1283352053\">" +
"<userName>Guest</userName>" +
"</chatLogin>" +
"<adminLogin hasCam=\"false\" ip=\"127.0.0.1\" ts=\"1283352053\">" +
"<userName>admin</userName>" +
"</adminLogin>" +
"<guestLogin hasCam=\"false\" ip=\"127.0.0.1\" ts=\"1283352020\">" +
"<userName>guest</userName>" +
"</guestLogin>" +
"<loginResult ip=\"127.0.0.1\" id=\"1\" error=\"\" ts=\"1283351406\" />" +
"<joinRoom id=\"1\" roomID=\"z11283351417236\" ts=\"1283351417\" />" +
"<leaveRoom id=\"1\" roomID=\"room1\" ts=\"1283351426\" />" +
"<createRoom id=\"1\" ts=\"1283351417\">" +
"<roomName>test</roomName>" +
"</createRoom>" +
"<sendFile id=\"2\" receiverID=\"1\" fileID=\"1283351441141\" fileSize=\"6Kb\" ts=\"1283351441\">" +
"<fileName>script.txt</fileName>" +
"</sendFile>" +
"<acceptFile id=\"1\" senderID=\"2\" isAccept=\"true\" fileID=\"1283351441141\" ts=\"1283351444\" />" +
"<changeColor id=\"1\" color=\"6684876\" ts=\"1283351406\" />" +
"<changeAvatar id=\"1\" avatarID=\"02\" ts=\"1283351406\" />" +
"<changeStatus id=\"2\" status=\"1\" ts=\"1283351383\" />" +
"<publish id=\"1\" video=\"false\" audio=\"true\" pause=\"false\" ts=\"1283351421\" />" +
"<subscribe id=\"1\" publisherID=\"2\" roomID=\"proom2000\" ts=\"1283351998\" />" +
"<unsubscribe id=\"1\" publisherID=\"2\" roomID=\"proom2000\" ts=\"1283351998\" />" +
"<sendInvitation id=\"1\" receiverID=\"2\" roomID=\"null\" ts=\"1283351494\" />" +
"<answerInvitation id=\"2\" senderID=\"1\" roomID=\"null\" accepted=\"true\" ts=\"1283351499\" />" +
"<startRecordVideo userID=\"1\" ts=\"1283351499\" />" +
"<videoSaved userID=\"1\" fileName=\"someFile.flv\" fileSize=\"1234121234\" ts=\"1283351499\" />" +
"</logPro>";
}
else if (!string.IsNullOrEmpty(s))
{
doc.InnerXml = s;
}
XML oXML = new XML();
oXML.parseXML(doc);
Response.Write("Done");
Response.End();
}
/*
*
*
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[chat7_logpro](
[log_id] [int] IDENTITY(1,1) NOT NULL,
[action] [nchar](40) NULL,
[ip] [nchar](40) NULL,
[ts] [nchar](40) NULL,
[uid] [nchar](70) NULL,
[userName] [nchar](70) NULL,
[hasCam] [nchar](40) NULL,
[id] [nchar](40) NULL,
[error] [nchar](250) NULL,
[roomID] [nchar](70) NULL,
[roomName] [nchar](70) NULL,
[receiverID] [nchar](70) NULL,
[fileSize] [nchar](70) NULL,
[fileName] [nchar](70) NULL,
[senderID] [nchar](70) NULL,
[isAccept] [nchar](70) NULL,
[fileID] [nchar](70) NULL,
[color] [nchar](70) NULL,
[avatarID] [nchar](70) NULL,
[status] [nchar](70) NULL,
[video] [nchar](40) NULL,
[audio] [nchar](40) NULL,
[pause] [nchar](40) NULL,
[publisherID] [nchar](40) NULL,
[accepted] [nchar](40) NULL,
[userID] [nchar](40) NULL
) ON [PRIMARY]
GO
*
*/
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>blah blah</title>
</head>
<body>
<form id="Form1" method="post" runat="server"><% Page_Load(null, null); %></form>
</body>
</html>
答案 0 :(得分:2)
最明显的问题是您使用类的实例打开数据库连接XML实例化。
因此,对于该对象的生命,连接是开放的。你的理由是什么?
您应该只在需要时打开连接,然后在完成后关闭它。将用于打开连接的代码放在using语句中将处置连接,因此您不必手动处理连接,就像在上面的代码中一样。
这是一个例子,我没有测试,只是一个例子:
public void add2Db(string table, string sqlRows, string sqlValues)
{
string sql = "INSERT INTO " + table + " (" + sqlRows + ") VALUES (" + sqlValues + ")";
using(SqlConnection dbConn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString())
{
SqlCommand cmd = new SqlCommand(sql, dbConn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
您还应该查看Sql Injection攻击是什么。
答案 1 :(得分:1)
我不确定您的具体问题是什么,但您可能最好使用using
语句来管理数据库连接:
string sql = "INSERT INTO " + ...;
using(SqlConnection dbConn = new SqlConnection(ConfigurationManager.ConnectionStrings["..."].ConnectionString)){
//create your SqlCommand
SqlCommand cmd = ...;
//THEN open your database -- keep the connection open as short as possible
dbConn.Open();
//execute the query
cmd.ExecuteNonQuery();
}
离开using
语句后,Dispose()
会在您的SqlConnection
上调用SqlCommand
,这将关闭您的连接。您也可以在using
中创建IDisposable
,因为它还会实现{{1}}。
正如kprobst所提到的,建议不要使用析构函数来处理数据库连接。
答案 2 :(得分:0)
您正在关闭类析构函数中的连接,这不能保证在任何特定时间点执行。
相反,使用using(x)
块来管理类方法中连接的生命周期,并且不必担心何时会对类的特定实例进行垃圾回收。或者只是在函数中放置一个try / catch块并手动关闭连接。