gpt4 book ai didi

c# - Oracle 更改通知包含无效操作

转载 作者:行者123 更新时间:2023-11-30 18:14:11 25 4
gpt4 key购买 nike

设置

我创建了一个针对 .NET 4.7.2 的控制台应用程序并安装了 NuGet 包 Oracle.ManagedDataAccess版本 12.2.1100(最新/当前)使用 2 个查询设置依赖关系以监视对 MYTABLE 所做的更改,这两个查询具有不同的 WHERE 子句。

我要连接的 Oracle 数据库服务器在本地主机上运行,​​版本为 12.2.0.1.0。

在监听通知的控制台应用程序旁边,我使用 Oracle SQL Developer (v18.1.0.095) 实际向 MYTABLE 插入或更新记录以强制发出通知。

代码

using (var connection = new OracleConnection("Data Source=//localhost:1521/ORCL;Persist Security Info=True;User ID=SYSTEM;Password=password"))
{
OracleDependency.Port = 3005;

var dependency = new OracleDependency();
dependency.OnChange += (sender, eventArgs) =>
{
Console.WriteLine($"Change count: {eventArgs.Details.Rows.Count}");

// Columns in row: string ResourceName, int Info, string Rowid, long QueryId
foreach (DataRow row in eventArgs.Details.Rows)
{
var resourceName = (string)row["ResourceName"];
var info = (OracleNotificationInfo)row["Info"];
var rowId = (string)row["rowid"];
var queryId = (long)row["QueryId"];

Console.WriteLine($"{queryId} {info} {rowId} {resourceName}");
}
};

connection.Open();

var command1 = new OracleCommand("SELECT * FROM MYTABLE WHERE NAME = 'N1'", connection);
dependency.AddCommandDependency(command1);
command1.Notification.IsNotifiedOnce = false;
command1.AddRowid = true;
command1.ExecuteNonQuery();

var command2 = new OracleCommand("SELECT * FROM MYTABLE WHERE NAME = 'N2'", connection);
dependency.AddCommandDependency(command2);
command2.Notification.IsNotifiedOnce = false;
command2.AddRowid = true;
command2.ExecuteNonQuery();

Console.ReadKey();
}

行为

一旦我在一个事务中触发多个命令依赖项,我就会在通知中收到两倍多的事件行,并且无法再区分触发它的查询 ID。

在一个事务中运行此查询:

INSERT INTO MYTABLE (NAME) VALUES ('N1');

输出:

Change count: 1
63 Insert AAAR6CAABAAALohABJ SYSTEM.MYTABLE

在一个事务中运行此查询:

INSERT INTO MYTABLE (NAME) VALUES ('N2');

输出:

Change count: 1
64 Insert AAAR6CAABAAALohABK SYSTEM.MYTABLE

但是,当在一个事务中运行这个查询时:

INSERT INTO MYTABLE (NAME) VALUES ('N1');
INSERT INTO MYTABLE (NAME) VALUES ('N2');

我得到这个输出:

Change count: 4
63 Insert AAAR6CAABAAALohABH SYSTEM.MYTABLE
63 Insert AAAR6CAABAAALohABI SYSTEM.MYTABLE
64 Insert AAAR6CAABAAALohABH SYSTEM.MYTABLE
64 Insert AAAR6CAABAAALohABI SYSTEM.MYTABLE

虽然我希望:

Change count: 2
63 Insert AAAR6CAABAAALohABH SYSTEM.MYTABLE
64 Insert AAAR6CAABAAALohABI SYSTEM.MYTABLE

此外,当我执行触发第一个命令的 INSERT 和触发第二个命令的 UPDATE 时,我得到 4 行 INSERT + UPDATE 用于第一个 QueryId (63) 和 INSERT + UPDATE 用于第二个 QueryId (64),所以现在我可以区分它们了。

在多个 OracleDependency 类甚至多个连接上分离命令依赖性会导致相同的结果。

不知道有没有人知道这是怎么回事?

最佳答案

可能使用具有两个 OracleCommand 的相同 OracleDependency 实例会导致此行为。

Oracle docs 中的备注 部分AddCommandDependency 表示这是可能的,但它似乎不是默认配置。

我建议使用两个单独的 OracleDependency 实例。我们不知道两个查询的聚合是如何在内部完成的,但我猜测 ODP.NET 可能以某种方式将两个查询聚合为一个,使用的语法在“保证”模式下不受支持。

这会导致通知使用“尽力而为”模式,文档中指出该模式容易出现误报。

似乎没有办法知道在使用 ODP.NET 时使用了哪种模式,但我猜该模式是从查询中自动检测到的,并且记录了每种模式的查询约束 here .

关于c# - Oracle 更改通知包含无效操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50875634/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com