我通过他们用于.NET的官方托管驱动程序(Nuget包)使用Oracle。
我的应用程序从一开始就使用与数据库相同的连接,并从多个位置使用它来执行查询。
在某些情况下,可能存在导致异常的连接“打嗝”。问题是我不知道在发生这种情况时重试执行查询的最佳策略是什么。
有没有一种解决这种情况的常用方法?
谢谢。
答案 0 :(得分:1)
我同意哈比卜的评论。
oracle .NET Package使用连接池。即使您打开多个连接,它也会相应地管理它们,这样您就不必保持打开状态。
这意味着您的代码可以简化为类似这样的伪代码:
using(OracleConnection conn = MakeConnection())
{
//do stuff with connection
//not necessary, but I always manually close connection. Doesn't hurt.
conn.Close();
}
如果你不确定连接问题,即使是在那么小的执行中,你可以将它包装在try-catch块中,如下所示:
try
{
using(OracleConnection conn = MakeConnection())
{
//do stuff with connection
//not necessary, but I always manually close connection. Doesn't hurt.
conn.Close();
}
}
catch(OracleException ex)
{
//handle exception.
}
OracleException看起来是.NET oracle包的主要异常。请注意,您可能想要更具体地捕捉其他人。
答案 1 :(得分:1)
在进行查询时,动态实例化连接会更容易。我不认为一个简单的try / catch会帮助你,因为即使你重新初始化catch块中的连接,你也必须以某种方式重新执行你的查询。
我不建议这样做,但如果发现异常,你可以使用重新初始化连接的Retry类....
public class Retry
{
public static void Do(Action action, TimeSpan retryInterval, int retryCount = 3)
{
Do<object>(() =>
{
action();
return null;
},
retryInterval, retryCount);
}
public static T Do<T>(Func<T> action, TimeSpan retryInterval, int retryCount = 3)
{
var exceptions = new List<Exception>();
for (int retry = 0; retry < retryCount; retry++)
{
try
{
if (retry > 0)
Thread.Sleep(retryInterval);
return action();
}
catch (ConnectionException ex)
{
// ***Handle the reconnection in here***
exceptions.Add(ex);
}
}
throw new AggregateException(exceptions);
}
}
然后您可以像
一样调用您的查询Retry.Do(() => MyQueryMethod, TimeSpan.FromSeconds(5));
我很久以前从SO获得了这个重试代码的基础,不记得线程,但它不是我原来的代码。虽然我已经用了很多东西了。