【问题标题】:How to handle database exceptions in .NET?如何处理 .NET 中的数据库异常?
【发布时间】:2016-04-20 18:24:28
【问题描述】:

我通过他们的 .NET 官方托管驱动程序(Nuget 包)使用 Oracle。

我的应用程序从一开始就使用与数据库相同的连接,并在多个位置使用它来执行查询。

在某些情况下,可能会出现导致异常的连接“打嗝”。问题是我不知道发生这种情况时重试执行查询的最佳策略是什么。

有解决这种情况的通用方法吗?

谢谢。

【问题讨论】:

  • 说的挺宽泛的,但是你为什么用单连接,为什么不使用多连接,越晚打开连接越早关闭。

标签: c# .net oracle exception connection


【解决方案1】:

我同意 Habib 的评论。

oracle .NET 包使用连接池。即使您打开了多个连接,它也会相应地管理它们,因此您不必保持打开状态。

这意味着你的代码可以被简化成类似这样的伪代码:

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 包的主要异常。请注意,您可能想更具体地捕捉其他人。

【讨论】:

  • Using 块通常会处理 Connection.Close() 和 Connection.Dispose() ,即使在异常情况下也是如此。我们不需要在代码中指定它。
【解决方案2】:

在进行查询时动态实例化连接会更容易。我认为一个简单的 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 那里得到了这个重试代码的基础,不记得这个线程,但它不是我的原始代码。不过,我已经在某些事情上使用了它。

【讨论】:

    猜你喜欢
    • 2010-09-28
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多