cha*_*ara 0 c# asp.net asp.net-mvc transactions
我有以下使用事务的方法。
private string getDocumentDetailsByNumber(string DocNumber)
{
SqlTransaction transaction = DALDBConnection.SqlConnection.BeginTransaction();
try
{
DataSet DocNum = new DataSet();
string sDocNumber = "";
string[] taleNamesDoc = new string[1];
taleNamesDoc[0] = "docnumber";
SqlParameter[] paramDoc = new SqlParameter[1];
paramDoc[0] = new SqlParameter("@DocumentNumber", DocNumber.ToString().Trim());
SqlHelper.FillDataset(transaction, CommandType.StoredProcedure, "spGetDocumentDetailsByNumber", DocNum, taleNamesDoc, paramDoc);
string docTitle = DocNum.Tables["docnumber"].Rows[0][0].ToString();
transaction.Commit();
return docTitle;
}
catch (Exception ex)
{
transaction.Rollback();
throw ex;
}
}
Run Code Online (Sandbox Code Playgroud)
多次运行该方法后,用户最终收到以下错误消息。
在从池中获取连接之前经过的超时时间
发生错误是因为我尚未关闭连接并且连接池已溢出。
我尝试在提交事务之前关闭连接。
transaction.Connection.Close();
transaction.Commit();
Run Code Online (Sandbox Code Playgroud)
然后得到以下错误。
这个SqlTransaction已经完成;它不再可用
如何关闭连接以避免错误?
您无法使用单个连接耗尽池。您需要关闭正在使用的所有连接。最好在交易以一种或另一种方式结束之后。using块是几乎所有与数据库相关的对象的朋友。
顺便一提:
throw ex;
Run Code Online (Sandbox Code Playgroud)
这会通过替换原始堆栈跟踪来破坏您的异常。用:
throw;
Run Code Online (Sandbox Code Playgroud)
重新抛出您捕获的未更改的异常。
如前所述,您应该正确处理连接。我修改了你的代码来演示。请注意,您需要将连接字符串替换为您的连接字符串。
private string getDocumentDetailsByNumber(string DocNumber)
{
using (var connection = new SqlConnection("My Connection String"))
{
SqlTransaction transaction = connection.BeginTransaction();
DataSet DocNum = new DataSet();
string sDocNumber = "";
string[] taleNamesDoc = new string[1];
taleNamesDoc[0] = "docnumber";
SqlParameter[] paramDoc = new SqlParameter[1];
paramDoc[0] = new SqlParameter("@DocumentNumber", DocNumber.ToString().Trim());
SqlHelper.FillDataset(transaction, CommandType.StoredProcedure, "spGetDocumentDetailsByNumber", DocNum, taleNamesDoc, paramDoc);
string docTitle = DocNum.Tables["docnumber"].Rows[0][0].ToString();
transaction.Commit();
return docTitle;
} // Connection is disposed and cleaned up.
}
Run Code Online (Sandbox Code Playgroud)
建立新的连接成本低廉,不应该被拒绝。每一个称为数据库的数据库都应该像这样打开一个新数据库。通过维护连接而不是释放它,您也会从数据库中夺走资源。它的池中没有可以立即使用的无限数量的连接。
编辑
删除了评论中提到的 try/catch。如果在 using 块中抛出异常,则会发生回滚并且异常会在堆栈中传递。