【问题标题】:Some tricky quick way to validate oracle db connection验证 oracle 数据库连接的一些棘手的快速方法
【发布时间】:2012-03-06 10:39:07
【问题描述】:

我的 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 进行通信。 希望得到你的帮助,伙计们!提前致谢!

【问题讨论】:

  • 如果您询问如何确定您的 Oracle 连接字符串是否有效,请尝试连接它,如果失败则无效。如果您有其他问题,您可能应该在 question 中加入一个问题。
  • @M.Babcock 问题是您提出的连接检查非常慢,不能用于快速检查。顺便说一句,问题在问题的标题中。
  • 我一定错过了问号。如果您想要一种轻量级的方法来预先检查服务器是否存在,请打开与其端口的 telnet 连接。
  • @M.Babcock 这种方式是否足够强大以检查连接?它比 Eric J. 提供的更快吗?
  • 如果目标是查看服务器是否可用,那么它通常就足够了。除了知道有 something 正在监听端口(虽然 Oracle 端口是众所周知的)并且绝对会更快之外,它不提供任何保证。能够告诉用户他们的连接字符串是错误的就足够了(如果那是你所追求的)。为您的问题提供一些背景信息,我会告诉您这是否足够。

标签: c# .net oracle database-connection devart


【解决方案1】:

尝试执行一个成本非常低的操作,无论您连接到什么架构,该操作都应该有效,例如

选择 1

(该语句适用于 MS SQL 和 MySQL...应该也适用于 Oracle,但我无法确认)。

如果你得到你期望的结果(在这种情况下是一行,一列,包含一个“1”),那么连接是有效的。

至少有一个连接池管理器使用此策略定期验证连接。

更新:

这是您方法的 SQL Server 版本。您可能只需将“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;
    }
}

【讨论】:

  • 这真的很有趣。请您提供一些代码示例吗?
  • 关于什么的代码示例? SELECT 1?
  • 不,我要求重写整个IsConnectionActive 方法?它应该如何测试连接?只需连接到它,然后尝试执行查询?这种方法比 M.Babcock 提出的更快吗,你怎么看?
  • @EricJ。好,谢谢。我现在很清楚你的方法。
  • @kseen:M. Babcock 建议打开一个到端口的“telnet 会话”(实际上,打开一个到端口的 TCP/IP 连接)将是一个快速预检查是否有东西在监听另一方面,但在我看来,我编写的代码对于几乎任何要求都足够快。为此,您必须知道 Oracle 服务器正在侦听的端口。自从我做 Oracle 以来已经很久了,但我似乎记得端口信息可以在 TNS 名称文件或类似的文件中,可能不是默认的 Oracle 端口,也可能不在连接字符串中。我不会那样做。
【解决方案2】:

如果目标是简单地确定服务器是否位于 IP 地址或主机名,那么我建议使用 Ping(没有 3 次握手,并且开销低于 UDP 消息)。为此,您可以使用System.Net.NetworkInformation.Ping 类(参见其documentation 示例)。

如果您想证明在通用 Oracle 端口上确实存在监听,我建议使用 System.Net.Sockets.TcpClientSystem.Net.Sockets.Socket 类(他们的文档也提供示例)来提供此功能。

(到目前为止)最简单的方法是使用 Oracle API for C# 打开一个连接。有一个非常好的教程,其中包含代码here。它涵盖的不仅仅是连接,但您应该能够从其余部分中剥离连接部分以满足您的需求。

【讨论】:

    【解决方案3】:

    Oracle 有products and software 专门用于帮助维护高可用性,它可以让您通过连接字符串上名为HA Events=true 的设置从连接池中删除死连接。您的 Oracle DBA 需要确定您的安装是否支持它。

    【讨论】:

    • 你能解释得更详细些吗?
    • 从您的原始问题看来,您的数据库连接不可靠,如果连接断开,您希望将它们路由到其他数据库,对吗?
    • 不,我只是想确保连接有效。
    猜你喜欢
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 2019-03-14
    • 1970-01-01
    • 2021-09-19
    • 2013-02-02
    • 1970-01-01
    相关资源
    最近更新 更多