程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 使用MS Enterprise Library的DAAB獲取數據時拋出異常

使用MS Enterprise Library的DAAB獲取數據時拋出異常

編輯:關於.NET

開門見山,使用MS Enterprise Library的DAAB(Data Access Application Block)獲取 數據時拋出異常。具體場景如下,通過Database對象的ExecuteReader執行兩段Select語句, 前一句是不合法的,後一句是正確的。為了避免第一次執行出錯導致程序的終止,特意將其 放到Try/Catch酷快中。兩次數據庫操作通過TrsanctionScope的形式納入同一個Transaction 中,具體的代碼如下所示。 

class Program
{
    static void Main()
    {

        string invalidSql = "SELECT * FROM {InvalidTable}";
        string validSql = "SELECT * FROM {ValidTable}";

        Database db = DatabaseFactory.CreateDatabase();
        using (TransactionScope scope = new TransactionScope())
        {
            DbCommand commandWithInvalidSql = db.GetSqlStringCommand (invalidSql);
            DbCommand commandWithValidSql = db.GetSqlStringCommand (validSql);

            try
            {
                db.ExecuteReader(commandWithInvalidSql);
            }
            catch
            { }

            db.ExecuteReader(commandWithValidSql);
        }
    }
}

但是在執行第二個ExecuteReader方法的時候卻拋出如下一個InvalidOperationException (如下圖),錯誤消息為:“ExecuteReader requires an open and available Connection. The connection's current state is closed.” 

原因出在這裡:在ExecuteReader中,相應的ADO.NET代碼放在try|catch中,當異常拋出 後,相應的DbConnect會被關閉。但是由於在我的代碼中,兩次ExecuteReader的調用是在一 個相同的Ambient Transaction中執行的,DAAB在內部采用相同的DbTransaction執行這兩項 操作,當執行第一項操作時,由於出現異常導致DbConnect關閉,使用相同DbConnect的第二 項操作肯定會失敗。

public virtual IDataReader ExecuteReader(DbCommand command)
{
    ConnectionWrapper wrapper = GetOpenConnection(false);

    try
    {
//
// JS-L: I moved the PrepareCommand inside the try because it can fail.
//
PrepareCommand(command, wrapper.Connection);

//
// If there is a current transaction, we'll be using a shared connection, so we don't
// want to close the connection when we're done with the reader.
//
if (Transaction.Current != null)
    return DoExecuteReader(command, CommandBehavior.Default);
else
    return DoExecuteReader(command, CommandBehavior.CloseConnection);
    }
    catch
    {
wrapper.Connection.Close();
throw;
    }
}

我不清楚微軟在設計的時候,是因為沒有考慮到這種場景呢,還是不得以而為之,或者是 出於其他因素的考慮,大家有何見解。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved