我有以下部署:
A)服务器机器:
B)客户机:
在客户端计算机中,我有一个非常简单的应用程序,它执行以下步骤:
执行这些步骤后,我可以在DBA_CHANGE_NOTIFICATION_REGS表中看到已插入新记录。此记录中的信息与我的客户端设置(用户连接,IP地址,IP端口)完全匹配。
然后,我修改了数据库,确保在此修改后要通知的查询结果发生了变化。应该通知我的申请,但事实并非如此。
我已经检查过(使用Wireshark),在修改之后,一些流量通过DBA_CHANGE_NOTIFICATION_REGS中指定的端口从服务器发送到客户端,但是客户端应用程序没有得到通知。
因此,似乎正确创建了通知,还发送了从服务器到客户端计算机的通知,但通知未到达应用程序。
客户端还需要什么才能收到通知?
提前致谢....
这里是我正在使用的代码:
private void buttonConnectOracle_Click(object sender, EventArgs e)
{
String constr = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.164.10.202)(PORT=30005))" +
"(CONNECT_DATA=(SID=MASI)));User Id=dbuser;Password=dbuserpasswd;";
try
{
OracleCon = new OracleConnection(constr);
OracleCon.Open();
buttonConectarOracle.Enabled = false;
RegisterOracleCommandDependency();
}
catch (Exception E)
{
MessageBox.Show(String.Format("ERROR connecting with Oracle BD: {0}{0}Connection string: {1}{0}{0}Error:{0}{2}", "\n\r", constr, E.Message));
}
}
private void RegisterOracleCommandDependency()
{
String sql = "SELECT * FROM SCEHMA.REF";
OracleCommand command = new OracleCommand(sql, OracleCon);
OracleDep = new OracleDependency(command);
command.Notification.IsNotifiedOnce = false;
command.ExecuteNonQuery();
OracleDep.OnChange += new Oracle.DataAccess.Client.OnChangeEventHandler(OnMyNotificationOracle);
}
public void OnMyNotificationOracle(object src, OracleNotificationEventArgs args)
{
String logStr = "Notification received at " + DateTime.Now.ToString();
//TODO: Add logStr to log
}
答案 0 :(得分:1)
首先,感谢@b_levitt,@ yopez83和@Christian Shay的贡献。
问题已经解决:某些Oracle Server版本与相应的Oracle客户端版本之间存在不兼容问题。
总结一下,当Server为11.2.0.2.0且Client为11.2.0.1.2时,通知不起作用。
此查询提供有关Oracle服务器版本的信息:
select * from v$version;
就我而言,输出如下:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for 64-bit Windows: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
希望这有帮助......
答案 1 :(得分:1)
只是添加到上面列出的不兼容版本; 我在Oracle 11g 11.2.0.3.0版(64位)和使用ODP.NET(Oracle.ManagedDataAccess)版本12.1.24160719时遇到了同样的问题。
在USER_CHANGE_NOTIFICATION_REGS表中获取一个条目(主机IP与我的客户端IP不匹配,但是,嗯...)此条目在大约30秒后被删除。 OnChangeEventHandler在插入时从未在.Net客户端中触发(使用基于对象的通知)。
两者都做了:
GRANT CHANGE NOTIFICATION TO [USER]
GRANT EXECUTE ON DBMS_CHANGE_NOTIFICATION TO [USER]
尝试从nuget现在提供的其他ODP.NET客户端版本,低至10.1.21。没有用。执行插入时,Wireshark在端口1005(由OracleDependency使用)上检测不到任何流量。叹息。
更新:事实证明,由于在服务器上设置了IP重定向,回调失败了,所以在这种情况下不要责怪Oracle ......提示始终要验证IP地址在USER_CHANGE_NOTIFICATION_REGS中指定。
答案 2 :(得分:0)
检查documentation。我认为它可以帮助您完成通知。
另请参阅this,如果之前的链接没有帮助。
答案 3 :(得分:0)
也许这可以帮助
using (OracleConnection OraConn = new OracleConnection(conString))
{
using (OracleCommand OraComm = OraConn.CreateCommand())
{
try
{
OracleDependency OraDep = new OracleDependency(OraComm);
OraComm.AddRowid = true;
OraComm.CommandText = crawlORACLEServer;
OraComm.CommandType = System.Data.CommandType.Text;
OraComm.Notification.IsNotifiedOnce = false;
OraDep.OnChange += OraDep_OnChange;
if (OraConn.State == System.Data.ConnectionState.Closed) OraConn.Open();
dynamic f = await OraComm.ExecuteNonQueryAsync();
bRet = true;
}
catch (OracleNullValueException eN)
{
message = eN.Message;
}
catch (OracleTruncateException OT)
{
message = OT.Message;
}
catch (OracleTypeException eT)
{
message = eT.Message;
}
catch (OracleException ex)
{
message = ex.Message;
}
catch (Exception e)
{
message = e.Message;
}
finally
{
OraComm.Dispose();
OraConn.Dispose();
}
}
}