使用事务时关闭连接

本文关键字:连接 事务 | 更新日期: 2023-09-27 18:06:14

我有以下使用事务的方法。

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;
            }
    }

在多次运行该方法后,用户最终得到如下错误信息:

在获得连接之前所经过的超时时间池

发生错误,因为我没有关闭连接,连接池已经溢出。

我试图在提交事务之前关闭连接。

transaction.Connection.Close();  
transaction.Commit();

然后得到以下错误:

这个SqlTransaction已经完成;它不再可用

如何关闭连接以避免错误?

使用事务时关闭连接

不能通过使用单个连接耗尽池。您需要关闭正在使用的所有连接。最好是在事务以某种方式结束之后。对于几乎所有与数据库相关的对象,using块都是您的朋友。

By the way:

throw ex;

这会通过替换原来的堆栈跟踪来破坏你的异常。用途:

throw;

如前所述,您应该正确地处理连接。为了演示,我修改了您的代码。请注意,您需要将连接字符串替换为您的连接字符串。

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. 
}

打开新的连接是便宜的,不应该皱眉。每调用一个数据库,你都应该像这样打开一个新的。通过维护连接而不处理它,您也从数据库中拿走了资源。它的连接池中没有无限数量的连接可以一次使用。

编辑

删除了注释中提到的try/catch。如果在using块中抛出异常,则会发生回滚并将异常向上传递到堆栈。

你考虑过关闭它吗?关闭连接会很明显吗?

顺便说一句,任何实现IDIsposable的东西都应该被处置。,而不仅仅是关闭。SqlConnection实现了IDisposable。这与SqlTransaction无关——你违反了。net世界的基本规则,因为你没有处理一次性例程。