2

我正在尝试使用带有 C# 的 Oracle 更改通知让测试应用程序工作,但我没有在我的应用程序中收到回调通知。Oracle 数据库版本为 11.2.0.1.0。Oracle.DataAccess v.2.112.30。我可以通过查看 SYS.USER_CHANGE_NOTIFICATION_REGS 和 SYS.USER_CQ_NOTIFICATION_QUERIES 来确认查询已在 Oracle 中注册。但是,SYS.DBA_CHANGE_NOTIFICATION_REGS 中从未出现任何内容。

注册一直持续到我在表上提交事务。提交后几秒钟后注册消失,我的应用程序没有收到通知。

我已确保我的计算机正在侦听正确的端口,甚至尝试关闭任何可能阻止该端口的防火墙。

我确实有 GRANT CHANGE NOTIFICATION 到 MYSCHEMA,GRANT EXECUTE ON DBMS_CHANGE_NOTIFICATION 到 MYSCHEMA,并且 JOB_QUEUE_PROCESSES 设置为 1。

问题:

1) 注册是否应该在 SYS.DBA_CHANGE_NOTIFICATION_REGS 中可见,如果是,是什么导致它在 SYS.USER_CHANGE_NOTIFICATION_REGS 和 SYS.USER_CQ_NOTIFICATION_QUERIES 中可见时不可见?

2)什么可能导致提交后注册消失?

3) 什么可能导致我的应用程序通知失败?

这是我正在使用的 C# 代码,它与 Oracle 网站上的基本相同:

using System;
using System.Threading;
using System.Data;
using Oracle.DataAccess.Client;

namespace NotifyTest
{
    public class Program
    {
        public static bool IsNotified = false;

            public static void Main(string[] args)
        {
            string constr = "User Id=mySchema;Password=myPassword;Data Source=myOracleInstance";

            OracleDependency dep = null;

            try
            {
                using (var con = new OracleConnection(constr))
                {
                    Console.WriteLine("Registering query...");
                    var cmd = new OracleCommand("select * from mySchema.NOTIFY_TEST", con);
                    con.Open();

                    OracleDependency.Port = 1005;
                    dep = new OracleDependency(cmd);
                    dep.OnChange += OnMyNotificaton;

                    int queryRegistered = cmd.ExecuteNonQuery();

                    // If oracle returns -1, then the query is successfully registered
                    if (queryRegistered == -1)
                    {
                        Console.WriteLine("Query Registered...");
                        Console.WriteLine("Listening for Callback...");
                    }
                    else
                    {
                        Console.WriteLine("There was an error...");
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            // Loop while waiting for notification       
            while (IsNotified == false)
            {
                Thread.Sleep(100);
            }
        }

        public static void OnMyNotificaton(object sender, OracleNotificationEventArgs arg)
        {
            Console.WriteLine("Table change notification event is raised");
            Console.WriteLine(arg.Source.ToString());
            Console.WriteLine(arg.Info.ToString());
            Console.WriteLine(arg.Source.ToString());
            Console.WriteLine(arg.Type.ToString());
            IsNotified = true;
        }
    }
}
4

3 回答 3

2

只是想提供有关我如何解决此问题的更新。我将我的 Oracle.DataAccess.dll 从 v.2.112.3.0 更改为 v.2.112.1.2,它工作正常。

于 2013-02-11T16:17:25.967 回答
1

在 SYS.CHNF$_REG_INFO 属性 QOSFLAGS 中有 QOS_DEREG_NFY,它指定数据库应该在第一次通知时取消注册。

于 2020-11-05T18:59:51.683 回答
0

不确定,但 job_queue_processes (1) 的值有点低。Oracle 在内部执行各种维护和事件处理任务。为此,他们还使用 Job slave。提高 job_queue_processes(默认 1000)并检查故障排除 CQN 注册

于 2013-02-05T06:07:35.553 回答