2013-05-16 33 views
0

如何追蹤分佈式傳輸錯誤?有什麼方法可以確定所有連接仍然打開嗎?我需要找到未正確關閉的交易?追蹤分佈式傳輸錯誤

當我從適配器填充表時,出現偶然的分佈式事務錯誤,並顯示以下代碼。我懷疑這個錯誤可能不在這個代碼中,但這是錯誤往往會彈出的地方,只有在第二次嘗試時,第一個總是可以正常工作。

using (OracleConnection oraConnection = new OracleConnection(connectionString)){ 
using (OracleCommand oraCommand = new OracleCommand("DB_SCHEMA." + rmd.storedprocName, oraConnection)){ 
    oraCommand.CommandType = CommandType.StoredProcedure; 

    if (rmd.parameters != null){ 
     for (int i = 0; i <= rmd.parameters.GetUpperBound(0); i++) 
     { 
      OracleParameter oraParameter = new OracleParameter(); 
      oraParameter.ParameterName = rmd.parameterNames[ i ]; 
      oraParameter.OracleDbType = rmd.parameterTypes[ i ]; 
      oraParameter.Size = 15; 

      string dataType = oraParameter.OracleDbType.ToString().ToUpper(); 

      switch (dataType) 
      { 
       case "VARCHAR2": 
        oraParameter.Value = rmd.parameters[ i ].ToString(); 
        break; 
       case "CHAR": 
        oraParameter.Value = rmd.parameters[ i ].ToString(); 
        break; 
       case "NUMBER": 
        oraParameter.Value = Convert.ToDouble(rmd.parameters[ i ]); 
        break; 
       case "DATE": 
        oraParameter.Value = Convert.ToDateTime(rmd.parameters[ i ]); 
        break; 
       default: 
        oraParameter.Value = rmd.parameters[ i ].ToString(); 
        break; 
      } 

      oraCommand.Parameters.Add(oraParameter); 

     } 
    } 

    oraCommand.Parameters.Add("RS", Oracle.DataAccess.Client.OracleDbType.RefCursor).Direction = ParameterDirection.Output; 
    OracleDataAdapter oraDataAdapter = new OracleDataAdapter(oraCommand); 
    oraDataAdapter.Fill(dataTable); //< -- error is thrown here 
} 
} 

回答

0

我不知道究竟哪裏出了問題是源自,但我猜想這是由於使用的OracleDataAdapter而你已經有一個和OracleCommand對象OracleConnection

我認爲使用OracleDataReader填寫表格並調用Open()Close()方法把你的連接將更加清潔。

後您將所有的參數oraCommand試試這個,而不是你DataAdapter

oraConnection.Open(); 
    OracleDataReader dr = oraCommand.ExecuteReader(); 
    dataTable.Load(dr); 
    oraConnection.Close(); 

同樣,我不認爲這會一定「修復」您的交易錯誤,但它只能保證你在執行存儲過程時有一個打開的連接,從而使連接更易於管理。

下面是一個使用TransactionScope對象爲數據訪問的例子:

try 
    { 
     using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = IsolationLevel.ReadCommitted})) 
     try 
     { 
      CallYourDataAccessMethodsHere(); 
      scope.Complete(); 
     } 
     catch (Exception ex) 
     { 
      //Handle or log the error during the transaction 
     } 
    } 
    catch (Exception ex) 
    { 
     //This will catch a TransactionAbortedException and hopefully help track down the problem 
    } 
在MSDN
+0

,它說:「不止一個OracleDataReader可以在任何給定的時間打開。」 (http://msdn.microsoft.com/en-us/library/ab4kxd8h.aspx)所以我嘗試使用它打開多個連接,但我仍然有錯誤。 –

+0

再次想到,您可能需要考慮對所有數據訪問方法使用「TransactionScope」,以確保所有訪問和讀取都在數據庫所有事務的範圍內完成。另一種可能性是存儲過程本身出了問題,也許嘗試在那裏做一些錯誤處理而不是回滾?或者發佈存儲過程,我們可以看看。 –

+0

我在原來的答案中添加了一些代碼來演示如何使用'TransactionScope'對象。 –