Oracle Change Notification with C#を使用してテストアプリケーションを動作させようとしていますが、アプリケーションでコールバック通知を受信していません。OracleDBのバージョンは11.2.0.1.0です。Oracle.DataAccessv.2.112.30。SYS.USER_CHANGE_NOTIFICATION_REGSおよびSYS.USER_CQ_NOTIFICATION_QUERIESを表示することで、クエリがOracleに登録されていることを確認できます。ただし、SYS.DBA_CHANGE_NOTIFICATION_REGSには何も表示されません。
テーブルでトランザクションをコミットするまで、登録は保持されます。コミット後数秒後に登録が消え、アプリケーションが通知を受信しません。
コンピューターが正しいポートでリッスンしていることを確認し、ポートをブロックしている可能性のあるファイアウォールをオフにしようとしました。
MYSCHEMAへのGRANTCHANGENOTIFICATION、MYSCHEMAへのDBMS_CHANGE_NOTIFICATIONでの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#コードであり、基本的にOracleWebサイトのものと同じです。
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;
}
}
}