发布
社区首页 >问答首页 >Polly没有正确处理OracleExceptions ORA-03113和ORA-03114

Polly没有正确处理OracleExceptions ORA-03113和ORA-03114
EN

Stack Overflow用户
提问于 2021-04-30 07:39:57
回答 1查看 204关注 0票数 2

我先前关于Polly和Oracle Connectivity的问题如下

async await throwing error for Polly code while connecting to Oracle DB

通过扩展这一点,我尝试处理基于连接和FTP连接的多个Oracle异常。它能够正确地处理FTP异常。但是对于甲骨文来说,它不能处理0RA-03113和ORA-03114。

这是我实现的代码。

代码语言:javascript
代码运行次数:0
复制
static void Main()
    {
        var retryTimes = 100;
        var retryableOracleErrorCodes = new[] { "ORA-03113", "ORA-03114", "ORA-12543", "ORA-12170", "ORA-12154"  };

        RetryPolicy retryPolicyFTP = Policy
            .Handle<Xceed.Ftp.FtpInvalidStateException>()
            .WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(10));

        RetryPolicy retryPolicyFTP1 = Policy
            .Handle<Xceed.Ftp.FtpIOException>()
            .WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(10));

        RetryPolicy retryPolicyOracle = Policy
            .Handle<OracleException>(ex => retryableOracleErrorCodes.Any(errorCode => ex.Message.Contains(errorCode)))
            .RetryForever();

        retryPolicyFTP.Execute(() =>
        {
            retryPolicyFTP1.Execute(() =>
            {
                retryPolicyOracle.Execute(() =>
                {
                    ApplicationMain applicationMain = new ApplicationMain();
                    applicationMain.Start();
                });
            });
        });
    }

请你把这件事弄清楚..。为什么它不能处理特定的Oracle异常。我的意思是,如果我破坏了Program之间的连接,它应该保持沉默而不会抛出该异常,而且当连接可用时,它应该能够检索数据库记录。

为什么它没有沉默,为什么它是breaking...for ORA-03113和ORA-03114.引发的错误如下所示。

详细的例外情况如下。

代码语言:javascript
代码运行次数:0
复制
36722763    Source.FtpInternal1.Poll    Failed  2021-04-30 08:40:00 2021-04- 
30 08:40:04     Oracle.DataAccess.Client.OracleException ORA-03113: end-of- 
file on communication channel
Process ID: 149519
Session ID: 1655 Serial number: 65101    at 
Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, 
OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object 
src, String procedure, Boolean bCheck)
at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, 
OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* 
pOpoSqlValCtx, Object src, Boolean bCheck)
at Oracle.DataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, 
Boolean fillRequest, CommandBehavior behavior)
at Oracle.DataAccess.Client.OracleCommand.ExecuteReader()
at Data.MetaRecord.Fill(DataTable dataTable, RecordCommand recordCommand, 
Object[] parameterValues, FillResultType fillResultType) in 
C:\Data\MetaRecord.cs:line 1348
at Data.MetaRecord.FillWithComposites(RecordCommandCompositeCollection 
recordCommandComposites, RecordCommandComposite parentRecordCommandComposite, 
Object[] parameterValues, FillResultType fillResultType) in 
C:\Data\MetaRecord.cs:line 1537
at Data.MetaRecord.FillWithComposites(RecordCommandCompositeCollection 
recordCommandComposites, RecordCommandComposite parentRecordCommandComposite, 
Object[] parameterValues, FillResultType fillResultType) in 
C:\Data\MetaRecord.cs:line 1551
at Data.MetaRecord.FillWithComposites(RecordCommandCompositeCollection 
recordCommandComposites, RecordCommandComposite parentRecordCommandComposite, 
Object[] parameterValues, FillResultType fillResultType) in 
C:\Data\MetaRecord.cs:line 1551
at Data.MetaRecord.RetrieveByPrimaryKey(RecordRetrieveAttributes 
recordRetrieveAttributes, Object[] primaryKeyValues) in 
C:\Data\MetaRecord.cs:line 1830
at Data.MetaRecord.GetRecordByPrimaryKey(RecordGetAttributes 
recordGetAttributes, Object[] primaryKeyValues) in C:\Data\MetaRecord.cs:line 
873
at Data.MetaRecord.GetRecordByPrimaryKey(Object[] primaryKeyValues) in 
C:\Data\MetaRecord.cs:line 923
at Processors.ExecuteInfo.GetAndRegisterRecord(RecordType recordType, 
Object[] primaryKeyValues) in C:\Core\Processors\ExecuteInfo.cs:line 143
at Processors.InternalPoll.ProcessExecute(DataTransaction dataTransaction, 
ExecuteInfo executeInfo, ProcessInfo processInfo) in 
C:\Core\Processors\InternalPoll.cs:line 67
at Processors.Processor.Execute(ExecuteInfo executeInfo, ProcessInfo 
processInfo) in C:\Core\Processors\Processor.cs:line 184

这是我准备的最后代码,但它仍然没有抛出OracleException消息。

代码语言:javascript
代码运行次数:0
复制
var retryTimes = 100;
var retryableOracleErrorCodes = new[] { "ORA-03113", "ORA-03114", "ORA-12543", "ORA-12170", "ORA-12154" };

RetryPolicy retryPolicyFTP = Policy
    .Handle<Xceed.Ftp.FtpInvalidStateException>().Or<Xceed.Ftp.FtpIOException>()
    .WaitAndRetry(retryTimes, _ => TimeSpan.FromSeconds(10));

RetryPolicy retryPolicyOracle = Policy
    .Handle<OracleException>(ex => retryableOracleErrorCodes
                                    .Any(errorCode => ex.ToString().Contains(errorCode)))
    .RetryForever();

Policy.Wrap(retryPolicyFTP, retryPolicyOracle).Execute(() =>
{
    try
    {
         ApplicationMain applicationMain = new ApplicationMain();
         applicationMain.Start();
    }
    catch (OracleException oraEx)
    {
         MessageBox.Show(oraEx.Message.ToString());
    }
});

.Or<Exception>()添加到最终代码后获得以下消息

代码语言:javascript
代码运行次数:0
复制
Oracle.DataAccess.Client.OracleException ORA-03114: not connected to ORACLE    at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck)
   at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
   at Data.OraclePackageCommand.ExecuteNonQuery(OracleTransaction transaction) in C:\Core\Data\OraclePackageCommand.cs:line 74
   at Data.OraclePackageCommand.ExecuteNonQuery() in C:\Core\Data\OraclePackageCommand.cs:line 63
   at Data.OraclePackage.ExecuteServerHeartbeat(Int32 serverId, Int32 heartbeatInterval, DateTime processTime, Int32& processingStatusId, DateTime& lastHeartbeatTime, DateTime& nextHeartbeatTime, Int32& availableProcessCount, Boolean& recordModificationExists) in C:\Core\Data\OraclePackage.cs:line 2385
   at Processors.ServerInfo.Heartbeat(DateTime processTime, ServerProcessingStatus& heartbeatProcessingStatus, Int32& availableProcessCount, Boolean& recordModificationExists) in C:\Core\Processors\ServerInfo.cs:line 252
   at Processors.ServerManager.ThreadStart() in C:\Core\Processors\ServerManager.cs:line 337
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-03 07:28:04

TL:我认为你的问题的根本原因是被吞没的异常。

代码语言:javascript
代码运行次数:0
复制
try
{
     ApplicationMain applicationMain = new ApplicationMain();
     applicationMain.Start();
}
catch (OracleException oraEx)
{
     MessageBox.Show(oraEx.Message.ToString());
}

当抛出一个OracleException时,它将显示在UI上。

但是,该方法将结束,不会触发任何策略。

为了能够重现您的问题,我更改了以下内容:

我已经将第三方的例外替换为内置的

  • FtpInvalidStateException >> NotSupportedException
  • OracleException >> ArgumentException

我为每个triggered

  • I've定义了两个委托来输出异常消息,当策略是FaultyMethod

  • Lastly时,将最大重试和等待时间更改为更小的

  • ,我已经将要修饰的代码提取成一个单独的函数,名为FaultyMethod

  • Lastly--让FaultyMethod变得非常错误:)

主要与策略声明和使用

代码语言:javascript
代码运行次数:0
复制
static readonly string[] retryableErrorCodes = 
    new[] { "ORA-03113", "ORA-03114", "ORA-12543", "ORA-12170", "ORA-12154" };
const int retryTimes = 3;

static void Main()
{
    RetryPolicy retryForNotSupported = Policy
        .Handle<NotSupportedException>()
        .WaitAndRetry(
            retryTimes,
            _ => TimeSpan.FromSeconds(1),
            (ex, ts) => Console.WriteLine(ex.Message));

    RetryPolicy retryForArgument = Policy
        .Handle<ArgumentException>(ex =>
            retryableErrorCodes.Any(errorCode => ex.Message.Contains(errorCode)))
        .RetryForever(ex => Console.WriteLine(ex.Message));

    try
    {
        Policy.Wrap(retryForNotSupported, retryForArgument).Execute(FaultyMethod);
    } catch (Exception ex)
    {
        Console.WriteLine(ex);
        Environment.Exit(-1);
    }
    Console.WriteLine("Finished");
}

待装饰功能

代码语言:javascript
代码运行次数:0
复制
static int errorCount = -1;
static void FaultyMethod()
{
    try
    {
        if (++errorCount >= retryableErrorCodes.Length)
            throw new NotSupportedException();
        throw new ArgumentException($"{retryableErrorCodes[errorCount]}");
    }
    catch (ArgumentException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

如果运行此应用程序,您将看到以下内容:

代码语言:javascript
代码运行次数:0
复制
ORA-03113
Finished

  1. ArgumentException被抛出,ORA-03113
  2. The异常在FaultyMethod中被捕获,它的消息被打印出
  3. ,没有任何重试策略被触发
  4. ,没有异常被PolicyExecute抛出,这就是为什么已完成的被打印

现在,让我们将代码改为抛出NotSupportedException

代码语言:javascript
代码运行次数:0
复制
static void FaultyMethod()
{
    try
    {
        if(++errorCount <= retryTimes)
            throw new NotSupportedException();
        
        //if (++errorCount >= retryableErrorCodes.Length) 
        //    throw new ArgumentException($"{retryableErrorCodes[errorCount]}");
    }
    catch (ArgumentException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

然后输出将是:

代码语言:javascript
代码运行次数:0
复制
Specified method is not supported.
Specified method is not supported.
Specified method is not supported.
System.NotSupportedException: Specified method is not supported.
...

  1. FaultyMethod抛出NotSupportedException
  2. Its catch块不捕获此exception
  3. Inner重试策略,检查它是否是来自perspective
  4. No,的已处理异常--这不是--这就是为什么它将问题升级到外部策略
  5. 外部重试策略,检查它是否是来自perspective
  6. Yes,的已处理异常这就是为什么它在启动一个新的重试NotSupportedException
  7. Main's
  8. 之前等待1秒的原因--这个完全相同的序列(从1到6)在外部策略达到重试计数阈值时再重复2次
  9. ,然后它将抛出原始的异常,exits

try-catch会捕捉到这个异常,然后打印出来。

因此,如果您从FaultyMethod中删除了try-catch

代码语言:javascript
代码运行次数:0
复制
static void FaultyMethod()
{
    if (++errorCount >= retryableErrorCodes.Length)
        throw new NotSupportedException();
    throw new ArgumentException($"{retryableErrorCodes[errorCount]}");
}

然后输出将如下所示:

代码语言:javascript
代码运行次数:0
复制
ORA-03113
ORA-03114
ORA-12543
ORA-12170
ORA-12154
Specified method is not supported.
Specified method is not supported.
Specified method is not supported.
System.NotSupportedException: Specified method is not supported.

(infinite)

  • All
  • All ArgumentException由内部策略处理,不超过其重试计数,外部策略在超过其重试计数(3)

之前对NotSupportedException进行处理。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67330054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档