Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用事务时关闭连接_C#_Asp.net_Asp.net Mvc_Transactions - Fatal编程技术网

C# 使用事务时关闭连接

C# 使用事务时关闭连接,c#,asp.net,asp.net-mvc,transactions,C#,Asp.net,Asp.net Mvc,Transactions,我有以下使用事务的方法 private string getDocumentDetailsByNumber(string DocNumber) { SqlTransaction transaction = DALDBConnection.SqlConnection.BeginTransaction(); try { DataSet DocNum = new DataSet();

我有以下使用事务的方法

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();
在多次运行该方法后,用户最终收到下面的错误消息

从服务器获取连接之前经过的超时时间 水池

发生错误,因为我尚未关闭连接,并且连接池已溢出

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

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();
然后得到以下错误

此事务已完成;它不再可用


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

您是否考虑过呼叫关闭连接?很明显要关闭一个连接还是


顺便说一句,任何实现IDIsposable的东西都应该被处理掉,而不仅仅是关闭。SqlConnection实现了IDisposable。这与SqlTransaction无关-您违反了.NET世界的一条基本规则,不处理一次性例程。

您不能使用单个连接耗尽池。您需要关闭所有正在使用的连接。最好在交易以某种方式结束之后。几乎所有与数据库相关的对象都可以使用块

顺便说一下:

throw ex;
这会通过替换原始stacktrace来破坏您的异常。使用:

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块中引发异常,则将发生回滚,异常将向上传递到堆栈

您可以使用usingsqltransaction tran=newsqltransaction{//you code},因此如果我使用usingsqltransaction=DALDBConnection.SqlConnection.BeginTransaction{//my code},它会关闭连接吗?在return语句之后它是否仍然关闭连接?不,它没有。连接本身应该在using块中。将事务也放在using块中,将摆脱整个异常处理。嗯,我想我从未在using块中遇到过异常。在块中抛出时是否吞没异常?否,事务由使用块处理,导致回滚。异常是正常传递的,可以在更高级别捕获。这就是使用块的意义所在:它们将处理对象,不管它们是如何留下的。感谢您的澄清。我没有意识到它会在抛出异常时自动处理回滚。这是一条很好的信息。SqlTransaction=connection.BeginTransaction;抛出无效的操作。连接已关闭。