[問題記錄.Oracle/odp.net]託管ODP中,連接池的連接驗證參數(validate connection=true)無效?

問題描述:
使用ODP訪問Oracle時,某些情況會開啓連接池(如,存在併發訪問的情況,想節省每次訪問重新建立連接的時間)。但也會引來一些連接池的問題。如:遇到數據庫重啓、會話被kill等情況。此時直接使用從池裏取出的連接就會報特定的錯誤,需要清理掉重新創建連接。

有一個專門的連接串參數“validate connection”來控制,是否自動來做這個檢查(使用連接前,檢查從池中取出的連接是否仍然可用),只是會有額外的性能消耗,建議在實際環境中驗證具體影響。

多年前做過驗證,存在明顯的額外耗時,所以禁用了這個參數。只是針對特定錯誤類型,做連接池的清理。

switch (oraEx.Number)
{
    case 3113:  //ORA-03113: 通信通道的文件結尾- 可能發生於重啓數據庫之後重新連接時
        OracleConnection.ClearAllPools();
        throw new Exception("發生ORA-03113錯誤,已清空數據庫連接池。", ex);
    case 28:    //ORA-00028: 會話己被終止 -  kill會話時可能發生00028或03111異常
    case 1012:  //ORA-01012: 沒有登錄(not logon) - 發生在ORA-00028後再訪問數據庫
    case 1013:  //ORA-01013: 用戶請求取消當前的操作
    case 2396:  //ORA-02396: 超出最大空閒時間(exceeded maximum idle time)
    case 3111:  //ORA-03111: 通信通道收到中斷 - kill會話時可能發生00028或03111異常
    case 3135:  //ORA-03135: 連接失去聯繫(connection lost contact)
    case 6508:  //ORA-06508: 無法找到正在調用的程序單元 - 存儲過程用了全局變量可能出現
    case 12535: //ORA-12535: TNS操作超時(TNS:operation timed out)
    case 12537: //ORA-12537: 網絡會話: 文件結束
    case 12570: //ORA-12570: 網絡會話:意外的數據包讀取錯誤
        if (conn != null)
        {
            OracleConnection.ClearPool(conn);
            throw new Exception("xxxxx", ex);
        }
        else
        {
            OracleConnection.ClearAllPools();
            throw new Exception("xxxxx", ex);
        }
    default:
        break;
}

 

這樣也挺好,只是。。。(常在河邊走,哪有不溼鞋)難免不會遇到新的狀況(如,“Oracle.ManagedDataAccess.Client.OracleException (0x80004005): 連接請求超時”)。如果沒有自動處理機制,問題要是發生在凌晨或業務高峯期就很不友好了。

所以,打算通過策略開啓“validate connection”參數。可沒想到的是,基於託管odp(Oracle.ManagedDataAccess.4.122.19.1.20191122)驗證居然木有效果。。木有效果。。。。。。能說什麼呢——對託管odp組件存在這樣和那樣的問題,早已見怪不怪了 - -||||||。   沒有oracle服務號,不去登記需求bug了。。。。。暫備案待查先

 

 

附錄:相關資料和參考
https://stackoverflow.com/questions/5726499/how-to-clear-the-odp-net-connection-pool-on-connection-errors
https://stackoverflow.com/questions/7845559/odp-net-connection-pooling-how-to-tell-if-a-connection-has-been-used
https://forums.asp.net/t/1701986.aspx?Oracle+Connection+to+Net+Connection+Pool
https://www.oracle.com/technetwork/database/windows/tom-091315.html
 

In this Document 

 Symptoms

 Cause 

 Solution

 References


APPLIES TO:

Oracle Data Provider for .NET - Version 10.2.0.1.0 and later
Microsoft Windows (32-bit)
Microsoft Windows x64 (64-bit)

***Checked for relevance on 24-May-2017*** 

SYMPTOMS

ODP.NET applications that have connection pooling enabled (which is the default) may intermittently experience the following error:

ORA-03135: connection lost contact

CAUSE

The nature of connection pooling is that there are frequently long lived idle connections, which may end up being disconnected by 3rd party software such as firewalls and load balancers.

Typically the exception occurs when trying to use a connection via a DataReader, DataAdapter, OracleCommand, etc, rather than during the OracleConnection::Open call.

For ease of troubleshooting, often the behavior can be reproduced from a SQLPlus session if left idle long enough.

SOLUTION


The ideal solution is to address the issue in the environment to prevent the disconnect from occurring, however several workarounds can be employed:

1) Simply catch the exception, and retry the operation.

2) Use the ODP.NET connection string parameter "validate connection=true" By default, it is set to false, which means that no checking of the connection is done when it is retrieved from the pool as a result of a OracleConnection::Open call. Setting it to true will cause ODP.NET to verify that the connection is still good by making a database round trip. If a problem with the connection is found, it is removed from the pool, and another connection is tried internally.

Note that while this typically alleviates ora-3135, it does have performance implications as every con.Open call will result in a round trip to the database. The overhead may or may not be significant depending upon application performance, so testing should be done in your environment.

3) Enable Dead Connection Detection on the database, which will result in a probe packet being sent from database to client periodically, which will usually prevent the firewall or load balancer from seeing the connection as idle.

Note 151972.1 Dead Connection Detection (DCD) Explained 

4) Connection pooling can be disabled entirely, but this will likely have a much larger performance impact.  To disable connection pooling, add "pooling=false" to the connection string.

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章