1

私のWCFサービスは、現在接続が利用可能であり、それを使用できるかどうかを確認する必要があります。多くのリモート データベースがあります。それらの接続は時々奇妙であり、データのクエリなどに使用できません。したがって、たとえば、これは使用される通常の接続文字列です。

User Id=user;Password=P@ssw0rd;Data Source=NVDB1;Connection Timeout=30

取得に使用されるサービスメソッドは次のとおりです

    public List<string> GetAliveDBs(string city)
    {
        if (String.IsNullOrEmpty(city))
            return null;                        

        List<string> cityDbs = (from l in alldbs where !String.IsNullOrEmpty(l.Value.city) && l.Value.city.ToUpper() == city.ToUpper() select l.Value.connString).ToList();            

        // There is no such city databases
        if (cityDbs.Count == 0)
            return null;

        ReaderWriterLockSlim locker = new ReaderWriterLockSlim();

        Parallel.ForEach(cityDbs, p =>
        {
            if (!IsConnectionActive(p.connString))
            {
                locker.EnterWriteLock();
                try
                {
                    cityDbs.RemoveAt(cityDbs.IndexOf(p));
                }
                finally
                {
                    locker.ExitWriteLock();
                }
            }
        });

        return cityDbs;
    }

    static public bool IsConnectionAlive(string connectionString)
    {
        using (OracleConnection c = new OracleConnection(connectionString))
        {
            try
            {                    
                c.Open();
                if ((c.State == ConnectionState.Open) && (c.Ping()))
                    return true;
                else
                    return false;
            }
            catch (Exception exc)
            {
                return false;                 
            }
        }
    }

Devart コンポーネントを使用して Oracle DB と通信します。皆さん、あなたの助けを願っています!前もって感謝します!

4

3 に答える 3

2

接続しているスキーマに関係なく機能する非常に低コストの操作を実行してみてください。

選択1

(そのステートメントはMS SQLとMySQLで機能します...Oracleでも機能するはずですが、それを確認することはできません)。

期待する結果(この場合は、「1」を含む1行、1列)が得られれば、接続は有効です。

少なくとも1つの接続プールマネージャーがこの戦略を使用して、接続を定期的に検証します。

アップデート:

これが、SQLServerバージョンのメソッドです。おそらく「SQL」を「Oracle」に置き換えることができます。

static public bool IsConnectionAlive(string connectionString)
{
    try
    {
        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            conn.Open();
            using (SqlCommand cmd = new SqlCommand("SELECT 1", conn))
            {
                int result = (int)cmd.ExecuteScalar();
                return (result == 1);
            }

        }
    }
    catch (Exception ex)
    {
        // You need to decide what to do here... e.g. does a malformed connection string mean the "connection isn't alive"?
        // Maybe return false, maybe log the error and re-throw the exception?
        throw;
    }
}
于 2012-02-15T03:28:47.253 に答える
1

サーバーが IP アドレスまたはホスト名に存在するかどうかを単純に判断することが目標である場合は、Ping をお勧めします (3 ウェイ ハンドシェイクはなく、UDP メッセージよりもオーバーヘッドが少なくなります)。System.Net.NetworkInformation.Pingこれにはクラスを使用できます(例については、そのドキュメントを参照してください)。

共通の Oracle ポートでリッスンしているものがあることを実際に証明したい場合は、System.Net.Sockets.TcpClientまたはSystem.Net.Sockets.Socketクラス (ドキュメントにも例が記載されています) を使用してこれを提供することをお勧めします。

これを行う最も簡単な方法は (断然)、Oracle API for C# を使用して接続を開くことです。ここにコードを含む非常に優れたチュートリアルがあります。接続だけではありませんが、ニーズに合わせて接続部分を残りの部分から取り除くことができるはずです.

于 2012-02-15T04:51:55.013 に答える
0

オラクルには、高可用性の維持を支援するための製品とソフトウェアがあり、接続文字列で呼び出される設定を介して接続プールから無効な接続を削除できますHA Events=true。Oracle DBA は、インストールがサポートされているかどうかを判断する必要があります。

于 2012-02-15T06:06:50.600 に答える