我正在尝试使用C#使用Oracle Change Notification来运行测试应用程序,但我没有在我的应用程序中收到回调通知。 Oracle DB版本为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中没有任何内容。
注册一直持续到我在表上提交事务为止。提交后几秒钟后注册消失,我的应用程序没有收到通知。
我确保我的计算机正在侦听正确的端口,甚至尝试关闭任何可能阻止该端口的防火墙。
我确实有MYSCHEMA的GRANT CHANGE通知,DBMS_CHANGE_NOTIFICATION到MYSCHEMA的GRANT EXECUTE,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;
}
}
}
答案 0 :(得分:2)
只想提供有关我如何解决此问题的更新。我将Oracle.DataAccess.dll从v.2.112.3.0更改为v.2.112.1.2,它运行正常。
答案 1 :(得分:0)
不确定但是job_queue_processes(1)上的值有点低。 Oracle在内部执行各种维护和事件处理任务。为此他们也使用Job奴隶。提高job_queue_processes(默认为1000)并检查Troubleshooting CQN Registrations
答案 2 :(得分:0)
在SYS.CHNF $ _REG_INFO属性QOSFLAGS中,有QOS_DEREG_NFY,它指定数据库应在第一条通知上取消注册。