我怎样才能防止反复自动连接到Oracle数据库?(How Can I Prevent Recurri

2019-09-24 02:03发布

背景

我们有一个C#/ VB.net客户端应用程序消耗它可以连接到Oracle数据库的WCF服务。 Web服务连接到使用用于Oracle的.NET Framework数据提供程序(不要与ODP混淆)数据库。 我们的测试者都经历过零星的Oracle帐户锁定,这似乎改变了用户的Oracle口令后不久发生。 该DBA_AUDIT_TRAIL日志揭示了什么似乎在非常有规律的时间间隔(即在点每两分钟),无需任何用户或客户端活动将自动连接尝试。 众多日志(IIS,WCF跟踪,消息记录等)已经证实这些连接尝试没有被客户端应用程序直接发起; 他们必须独立于Web服务或从System.Data.OracleClient的库里面到来。 自动尝试永远继续下去,直到Web服务的工作进程(单工)从闲置死亡。

在某些情况下,这些自动尝试获取密码更改之前开始,他们成功地连接到数据库,但只要更改密码,下一次尝试为无效的用户名/密码失败。 三次尝试后,该帐户被锁定。 我们正在努力寻找这些周期性连接尝试的来源。

我发现甲骨文的论坛上非常相似,但无人接听,问题在这里 。

当前思考

我们最新的调查已使我们相信它是连接池的意外行为。 如果用户的密码更改之前连接到网络服务,连接池将为原来的连接字符串创建。 更改密码并登录到Web服务后,数据提供者将创建一个基于新的连接字符串的新连接池。

可以在数据提供者里面的东西是试图保持从第一个连接池活着旧连接? 也许第一次连接池丢弃旧的连接,并试图用一个新的来补充它(与现在是无效的连接字符串)。 这是什么原因? 注意:我们使用默认设置最小/最大池大小(0/100)。

我们不相信我们的代码是直接试图访问从第一连接池的连接。 该用户的会话不具有前一交易日的密码的任何记忆,因此不会使用旧的连接字符串来引用第一连接池。 此外,没有在我们的代码可以解释我们所看到的非常精确的连接间隔。

Answer 1:

潜在的问题结束了未发行的数据库连接。 当打开一个连接时,它会检查了连接池。 如果连接永远不会关闭,池认为仍在使用它。 这导致池管理逻辑周期性地与使用原始的连接字符串的数据库进行重新认证。 当密码更改,这很快导致了失败的登录尝试和账号锁定。

// Problem logic; connection is never closed/returned to the connection pool.
public static void ConnPoolTest1()
{
    OracleConnection conn = new OracleConnection(connectionStringWithPooling);
    conn.Open();

    //...Do some work

    // Sit on this line for 5-10 minutes and examine Oracle's dba_audit_trail.
    Console.ReadKey(); // Since connection was never released back to the connection pool, the
                       // data provider's pool management will regularly re-authenticate with DB.
                       // If user's password changes before this process dies (releasing the
                       // connection pools), you start accumulating failed password attempts.
}

此问题的妥善解决办法是,以确保当你与他们所做的连接总是返回到池!

// Best practice: ALWAYS CLOSE YOUR CONNECTIONS WHEN YOU ARE DONE!
public static void ConnPoolTest2()
{
    OracleConnection conn = new OracleConnection(connectionStringWithPooling);
    conn.Open();

    //...Do some work

    conn.Close();

    // Sit on this line for 5-10 minutes and examine Oracle's dba_audit_trail.
    Console.ReadKey(); // No problem here! No recurring authentication attempts because the
                       // connection has been returned to the pool.
}

注意:其他答案建议关闭池和清理旧的连接池的时候,密码修改。 这些建议为我们工作的临时补丁,而我们搜索未发布的资源,他们极大地帮助我们找出问题。



Answer 2:

这可能会有点帮助。

甲骨文ODP.Net和连接池

OLE DB,ODBC,和Oracle连接池

基本上,在所述第二网页在那里,MSDN指出“一旦被创建,连接池不被破坏,直到活性处理结束。”。 看来,您的Web服务可能会抱着一种,它是有一些问题,所以许多连接/连接池。

所以我的建议:除了做多一点的故障排除与可能的连接增加了一些记录(也许只是一个文本文件),或者第一个链接有一个很好的命令来跟踪到数据库的连接,我会尝试关闭连接池目前。 你似乎有这个问题被称为“池碎片”。 这就是你有繁忙的马路上被通过管道连接池的所有数据库连接一台计算机。 这里最终会被如此多的池内存问题开始出现时和连接没有正确关闭。 这第二个是你的问题,如果连接没有关闭,或者可以说,你的密码更改命令使用旧的连接池,你将有问题的其他命令的列表之前执行。

最终,在你的情况,你就必须创建自己的网络连接池(不是用户),并通过自身的连接将数据送达回用户的单点(网络服务)。 这将意味着必须是不同类型的认证,由Web服务端处理,处理与用户的连接。 我敢肯定,很可能是太多的改变,现在在你的模型,但我会强烈建议找去找寻到底该解决方案。



Answer 3:

每当这将无效连接的任何事件发生,你需要销毁池,以便对池中的任何泄漏的连接和/或存活的适当标记,以防止再使用。 对于这一点,您要使用的clearpoolclearallpools数据提供者的方法。

http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracleconnection.clearpool.aspx

此外,全局异常管理器可以监听抛出无效的用户异常,并通过列举标识为连接字符串的一部分用户的连接销毁池。 可能效率不高,但应该把工作做好。



文章来源: How Can I Prevent Recurring Automatic Connections to Oracle Database?