簡體   English   中英

使用交易時關閉連接

[英]Close connection when using a Transaction

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

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塊是幾乎所有與數據庫相關的對象的朋友。

順便說說:

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塊中拋出異常,則會發生回滾並將異常傳遞到堆棧中。

您是否考慮過CALLNIG關閉? 關閉連接會很明顯嗎?

順便說一句,實現IDIsposable的任何事物都應該丟棄,而不僅僅是關閉。 SqlConnection實現IDisposable。 這與SqlTransaction無關-通過不處理可拋棄的例程來違反.NET世界的基本規則。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM