【发布时间】:2020-10-09 04:56:45
【问题描述】:
我将 ODP.NET 用于我的 MVC 项目,并且当数据库关闭然后再次恢复时,不断收到“-1000 连接请求超时错误”。一旦我回收 IIS AppPool,它就会开始工作。我尝试在 catch 块内使用 ClearAllPool()、ClearPool(connection) 来删除错误连接,但两者都不起作用。我在 StackOverflow 上找到了一篇文章,通过在连接字符串中添加 HA events=true 来使用快速连接故障转移。我也试过了,但没有运气。我问过 DBA,他们说默认情况下该功能在服务器端。我不知道为什么即使数据库已启动并正在运行,ODP.NET 仍在使用在数据库关闭时创建的旧的无效连接?我的所有代码也都包装在一个 using 块中,该块将关闭/处理连接。我的 Oracle.DataAccess 版本是 12.1.0。我阅读了谷歌上关于连接池、FCF 的每一页,但没有任何帮助。
我的连接字符串如下:
<add name="XXX"; providerName="Oracle.DataAccess.Client"; connectionString="DataSource=XXX;username=xxx;password=XXX;Pooling=True;Connection Timeout=120; Connection LifeTime=120; Validate Connection=True; Min Pool size=1;Max Pool size=180; HA events=true; Incr Pool size=5; Decr Pool size=2;"/>
这是我的 oracle 连接代码:
using(OracleConnection conn= new OracleConnection(connectionstring))
{
try
{
OracleCommand cmd=new OracleCommand("storedprocedure",conn)
{CommandType=CommandType.StoredProcedure};
//add parameters to command
foreach(var parmeter in parameters)
{
cmd.Parameters.Add(parameter);
}
conn.Open(); // this is where exception occurs
cmd.ExecuteNonQuery();
}
catch(OracleException ex)
{
if(conn.State=ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
//log exception ex in logfile
}
if(conn.State=ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
}
//Dispose All Parameters using Dispose() outside using statement.
foreach(var parmeter in parameters){
parameter.Dispose();
}
唯一的解决方案是当我设置 Pooling=False 时,我们不想这样做。
我使用了这些连接字符串属性,例如增加最小池大小、增加连接生命周期等,但似乎没有任何效果。
我将非常感谢这里的任何帮助。
谢谢。
【问题讨论】:
-
在您的连接池设置中是否有一个选项可以在使用连接之前测试连接(通常使用简单的查询,例如“select 1 from dual;”)?您尝试使用的 HA 功能仅在您有备用实例可以故障转移到的 Oracle RAC 配置中有效。在数据库实际上完全关闭的情况下,它们将无济于事。死连接通常必须由连接池检测和管理/重置,如果数据库关闭,则需要丢弃并重新连接。连接无法在数据库重新启动后继续存在。
-
感谢您的回复。不,我没有设置在使用之前测试连接。很抱歉,但此设置有什么帮助?
-
在将连接检出到应用程序之前将连接池设置为测试连接可确保在应用程序尝试使用它们之前识别出损坏的连接。这是大多数池的共同特征。除非您尝试将其用于某事,否则无法识别到 Oracle DB 的死连接,因此连接池识别坏连接、丢弃它们并替换它们以保持最小数量的可行连接非常重要。通常有一些设置可以启用测试、指定测试连接的频率、测试查询以及要维护的最小连接数。
-
如果您的数据库关闭/重新启动,那么您的所有连接都将中断,必须丢弃和更换。具有上述功能的连接池将不断尝试创建所需的最小连接数,直到成功,一旦恢复联机,就会自动登录回数据库。根据中断时间的长短和您的应用程序对延迟获取有效连接线程(以及数据库离线时可能中断的事务)的容忍度,这可能使您的应用程序能够以对最终用户透明的方式重新启动。
-
我认为这对我来说非常有意义。我将在我的代码中添加连接测试并检查它是否有效。再次感谢您的详细解释。
标签: c# asp.net-mvc oracle12c odp.net