验证oracle数据库连接的一些棘手的快速方法

时间:2012-02-15 03:23:12

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

我的WCF服务需要检查现在是否可用,我们是否可以使用它。我们有很多远程dbs。它们的连接有时很奇怪,不能用于查询数据或其他信息。 因此,例如,这是使用的常规连接字符串:

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进行通信。 伙计们,希望对你有所帮助!提前谢谢!

3 个答案:

答案 0 :(得分:2)

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

SELECT 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;
    }
}

答案 1 :(得分:1)

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

如果您希望证明在公共Oracle端口上实际上有某些内容,我建议使用System.Net.Sockets.TcpClientSystem.Net.Sockets.Socket类(他们的文档也提供示例)来提供此功能

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

答案 2 :(得分:0)

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