OracleChangeNotifications неправильно регистрируется в .NET Core 5.0

#.net #database #oracle #.net-core #f#

Вопрос:

У меня есть некоторый код, написанный на F#, с использованием .NET Core и ASP.NET Ядро. Предполагается, что он регистрирует прослушиватели изменений в базе данных, и время от времени он работает:

 namespace Raptor.ChangeListener.Oracle  open System open System.Data  open Microsoft.Extensions.Logging open Microsoft.Extensions.Options  open Oracle.ManagedDataAccess.Client  open Raptor.ChangeListener   [lt;Sealedgt;] type OracleChangeListenerOptions() =  member val ConnectionString = Unchecked.defaultoflt;stringgt; with get, set  member val Query = Unchecked.defaultoflt;stringgt; with get, set  member val Timeout = Unchecked.defaultoflt;TimeSpangt; with get, set   type OracleChangeListener(options: OracleChangeListenerOptions IOptions, logger: ILoggerlt;OracleChangeListenergt;) =  let options = options.Value   let mutable disposed = false  let sync = obj()  let mutable handlers: (Guid * Action) list = []   let mutable connection: OracleConnection = null  let mutable command : OracleCommand = null  let mutable dependency: OracleDependency = null   let startup =  async {  connection lt;- new OracleConnection(options.ConnectionString)  connection.StateChange.Add(fun state -gt;  if not disposed then  match state.CurrentState with  | ConnectionState.Broken -gt; logger.LogError(sprintf "Connection Broken: %s" options.Query)  | ConnectionState.Closed -gt; logger.LogError(sprintf "Connection Closed: %s" options.Query)  | _ -gt; ()  )   do! connection.OpenAsync() |gt; Async.AwaitTask    command lt;- new OracleCommand(options.Query, connection)  dependency lt;- new OracleDependency(command)   // these don't exist without first setting the dependency  command.Notification.IsNotifiedOnce lt;- false  command.Notification.Timeout lt;- int64 options.Timeout.TotalSeconds  let test = (command, dependency)   dependency.OnChange.Add(fun state -gt;  if not disposed then  try  logger.LogInformation(  let info = state.Info.ToString()  let typ = state.Type.ToString()  sprintf "%s Notification Change Type: %s, TableName: %A" info typ state.ResourceNames  )   for _, handler in handlers do  try  handler.Invoke()  with ex -gt;  logger.LogError(ex, "OracleChangeListener handler error")   with ex -gt;  logger.LogError(ex, "OracleChangeListener error")  )   match command.ExecuteNonQuery() with  | -1 -gt; ()  | n -gt; failwithf "Error Code In Listener: %i" n  }  |gt; Async.StartAsTask   interface IChangeListener with  member _.AddHandler handler =  lock sync (fun () -gt;  let key = Guid.NewGuid()  handlers lt;- List.append handlers [(key, handler)]   key  )   member _.RemoveHandler key =  lock sync (fun () -gt;  handlers lt;- handlers |gt; List.where (fun (k, _) -gt; k lt;gt; key)  )    interface IDisposable with  member this.Dispose() =  if not disposed then  disposed lt;- true // flag early for internal checks  if not (isNull dependency) then dependency.RemoveRegistration(connection)  if not (isNull command ) then command .Dispose()  if not (isNull connection) then connection.Dispose()  GC.SuppressFinalize(this)   [lt;Sealedgt;] type OracleChangeListenerlt;'TCategorygt;(options, logger) =  inherit OracleChangeListener(options, logger)  interface IChangeListenerlt;'TCategorygt;  

когда я выбираю из DBA_CHANGE_NOTIFICATION_REGS базы данных, я вижу все необходимые регистрации на месте:

действительные регистрации

Но чаще всего, и я не могу определить, в чем причина этого, регистрации производятся с портом -1 вместо действительного номера порта, например так:

недействительные регистрации

Когда это происходит, ни одна из служб не получает надлежащего уведомления об изменении зарегистрированных таблиц. Кроме того, все недопустимые строки удаляются при изменении, которое должно вызвать уведомление.