C#操作Oracle資料庫連接逾時的錯誤處理

來源:互聯網
上載者:User

 C#操作Oracle資料庫連接逾時的錯誤處理
 
 建立時間: 2007/08/09
 
 最近在使用C#操作Oracle資料庫時發現了一個奇怪的問題, 在資料庫會話存在逾時限制時, 即使用戶端重新串連資料庫也無法繼續資料庫操作, 而且在串連時沒有錯誤發生, 僅僅是 在串連後的操作中引發異常.
 
 程式本身很簡單, 從一個訊息中介軟體(MOM)中接收訊息資料, 然後儲存到資料庫. 由於該應用是一個後台服務, 需要對錯誤處理比較小心, 因為與存在使用者互動(介面)的程式相比,  後台服務需要更加健壯和更好的容錯能力.
 
 因此在操作資料庫時, 如果出現資料庫連接問題而無法儲存訊息的情況, 應當不丟失訊息並重新嘗試串連資料庫, 然後再次對訊息進行處理.
 對於其它類型的錯誤, 例如主/外鍵問題, 資料類型問題等等因為訊息資料本身錯誤引發的異常, 則應當儲存到檔案中, 並記錄日誌, 供人工審核, 然後對下面的訊息資料進行進行處理.
 
 因此程式碼中對ORA-00028(session kill) ORA-02396(exceed idle time) ORA-01012(not logon)和 ORA-12535(timeout)等錯誤進行單獨處理, 退出訊息處理函數, 並在主函數中重新調用,  以重新串連資料庫等資源.
 
  在服務主函數中:
  while (true)
            { try
                {
                    ProcessMessage(queueName);
                }
                catch (Exception e)
                {
                    LogManager.WriteLog(201, e.Message);
                    GC.Collect();
                }

                //Sleep
                if (mre.WaitOne(cf.TIME_OUT, false))
                    break;
  }
 
  而在訊息處理函數中:
  private static void ProcessMessage(String queueName)
        {
            //Open database
            String strConn = cf.DB_CONN_STR;
            OracleConnection oc = new OracleConnection(strConn);
            oc.Open();
    
     //串連MOM....(略)
           
            do
            {
              //讀取MOM訊息資料...(略)
                    try
                    {
                        //儲存MOM訊息資料到資料庫的操作...(略)
                       
                        str = msgInfo.MsgName + " save to database success.";
                        LogManager.WriteLog(301, str);
                    }
                    catch (OracleException e)
                    {
                        //In case of:   ORA-00028(session kill)
                        //              ORA-02396(exceed idle time)
                        //            ORA-01012(not logon)
                        //            ORA-12535(timeout)
                        if (e.Code == 2396 || e.Code == 1012 || e.Code == 28 || e.Code == 12535)
                        {
                            str = msgInfo.MsgName + " save to database fail, error code: " + e.Code.ToString() +", send message back and re-connect oracle.";
                            LogManager.WriteLog(301, str);

                            break; //quit loops
                        }
                        else //For other reason, just save data to dump file
                        {
                           //儲存MOM訊息資料到檔案...(略)
                        }
                    }

                    catch (Exception e)
                    {
                        //儲存MOM訊息資料到檔案...(略)
                    }
                }

             } while (true);

            oc.Close();
        }
       
        然而在測試中, 發現對ORA-00028(session kill)  ORA-01012(not logon)和 ORA-12535(timeout)均可成功的進行自動連接, 從而進行進行訊息處理, 而對ORA-02396(exceed idle time) 的情況, 串連沒有發現錯誤, 但是儲存操作失敗, 最終導致剩餘的訊息在資料庫正常的情況下也無法進行處理了.
       
        對於存在資源限制的資料庫, 均可出現上述問題, 因為後台服務一般是常串連.
        CREATE PROFILE developer_prof LIMIT
        IDLE_TIME 60
        CONNECT_TIME 480;
 
         ALTER SYSTEM SET RESOURCE_LIMIT=TRUE;
       
        在排除程式邏輯錯誤和資料庫問題後, 唯一的疑點就是串連池, 也就是資料庫重新串連時, 從用戶端串連池中取出了一個現存的串連, 以提供效率, 但是正是這個串連已經 逾時, 因此串連成功後, 操作還是引發了逾時錯誤. 因此必須清除該串連池, 然後重新串連. 對.NET FRAMEWORK2.0版中OracleConnection新增了靜態函數ClearPool和ClearAllPool.
        ClearPool方法在串連池中清除特定串連(通過參數指定)。如果在調用時該串連正在使用,則會對它們進行適當地標記,當該串連Close時,串連將被丟棄而不儲存到串連池中。
 ClearAllPools則在串連池中清除所有串連。如果在調用該方法時串連正在使用,則會對串連進行適當地標記,當對串連調用 Close 時,串連將被丟棄而不儲存到串連池。

        因此解決方案很簡單, 在適當的地方添加串連池清除操作, 可以選擇對所有異常出現的情況, 也可以針對連線逾時等需要清空串連池的情況.例如:
       
        if (e.Code == 2396)
        {
            //Clear connection pool and close connection
            OracleConnection.ClearPool(oc);
           
            str = msgInfo.MsgName + " save to database fail, error code: " + e.Code.ToString() +", send message back and re-connect oracle.";
            LogManager.WriteLog(301, str);

            break; //quit loops
       }
         

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.