我先前关于Polly和Oracle Connectivity的问题如下
async await throwing error for Polly code while connecting to Oracle DB
通过扩展这一点,我尝试处理基于连接和FTP连接的多个Oracle异常。它能够正确地处理FTP异常。但是对于甲骨文来说,它不能处理0RA-03113和ORA-03114。
这是我实现的代码。
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.引发的错误如下所示。
详细的例外情况如下。
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消息。
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>()
添加到最终代码后获得以下消息
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
发布于 2021-05-03 07:28:04
TL:我认为你的问题的根本原因是被吞没的异常。
try
{
ApplicationMain applicationMain = new ApplicationMain();
applicationMain.Start();
}
catch (OracleException oraEx)
{
MessageBox.Show(oraEx.Message.ToString());
}
当抛出一个OracleException
时,它将显示在UI上。
但是,该方法将结束,不会触发任何策略。
为了能够重现您的问题,我更改了以下内容:
我已经将第三方的例外替换为内置的
FtpInvalidStateException
>> NotSupportedException
OracleException
>> ArgumentException
。
我为每个triggered
FaultyMethod
FaultyMethod
FaultyMethod
变得非常错误:)主要与策略声明和使用
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");
}
待装饰功能
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);
}
}
如果运行此应用程序,您将看到以下内容:
ORA-03113
Finished
ArgumentException
被抛出,ORA-03113
FaultyMethod
中被捕获,它的消息被打印出Policy
的Execute
抛出,这就是为什么已完成的被打印。
现在,让我们将代码改为抛出NotSupportedException
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);
}
}
然后输出将是:
Specified method is not supported.
Specified method is not supported.
Specified method is not supported.
System.NotSupportedException: Specified method is not supported.
...
FaultyMethod
抛出NotSupportedException
NotSupportedException
Main
's try-catch会捕捉到这个异常,然后打印出来。
因此,如果您从FaultyMethod
中删除了try-catch
static void FaultyMethod()
{
if (++errorCount >= retryableErrorCodes.Length)
throw new NotSupportedException();
throw new ArgumentException($"{retryableErrorCodes[errorCount]}");
}
然后输出将如下所示:
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)
ArgumentException
由内部策略处理,不超过其重试计数,外部策略在超过其重试计数(3)之前对NotSupportedException
进行处理。
https://stackoverflow.com/questions/67330054
复制相似问题