使用 ArrayBinding 在 Oracle 上插入 table 时客户端应用程序挂起

Client application hangs when inserting into table on Oracle using ArrayBinding

这是我们的环境:

.网络版本:4.5

数据库:Oracle 12.1.0.2 (odp.net)

我们正在使用 LLBL "Adapter",但我认为这与问题无关

LLBLGen 专业版:4.1

Llbl Gen Pro 运行时:4.1.13.1213

当我们执行插入时(总是插入到我们短期使用然后删除的不同表中),我们使用以下代码:

int numRecords = strings.Count();
var insertCmd = "insert into " + tableName + " (StringField) values (:StringField)";

var oracleCommand = new OracleCommand();    
oracleCommand.CommandText = insertCmd;
oracleCommand.CommandType = CommandType.Text;
oracleCommand.BindByName = true;
oracleCommand.ArrayBindCount = numRecords;

oracleCommand.Parameters.Add(":StringField", OracleDbType.NVarchar2, strings.ToArray(), ParameterDirection.Input);               

// this is an LLBL adapter.  Like I said, I think the issue is below the LLBL layer.
this.adapter.ExecuteActionQuery(new ActionQuery(oracleCommand));

当数据库受到多个并行插入的严重打击时,我们会收到以下错误,并且从未从数据库中调用插入 returns。

ORA-12592: TNS:bad 数据包

ORA-12592: TNS:bad 数据包

ORA-12592: TNS:bad 数据包

ORA-12592: TNS:bad 数据包

ORA-03111: 在通信通道上收到中断

ORA-03111: 在通信通道上收到中断

ORA-03111: 在通信通道上收到中断

在数据库上,使用 Toad 的会话浏览器,我可以看到 "Current Statement" 是正确的。 插入 schemaX.tableY(StringField) 值(:Stringfield)

在 Toad 的“等待”选项卡下,有以下消息: “正在等待 SQL*来自客户端的净更多数据 - 到目前为止已等待 X 百秒”并且 X 不断递增,直到我们达到数据库超时。

我们尝试了 100 万个批次,这为我们的场景提供了最佳性能。然而,这个悬而未决的问题出现了。然后我将 ArrayBindCount 减少到 500K、100K、50K、10K,然后是 5K。只有当我使用 5K 时它才停止发生。

一些注意事项:

  1. 当数据库与客户端位于不同的物理机器上时,这种情况会更频繁地发生。使用本地 VM 时,这种情况很少发生。我们使用的网络通常非常可靠,没有其他值得注意的问题。

  2. 从错误消息(ORA-12592: TNS:bad packet)来看,问题似乎出在客户端,可能与"Oracle.DataAccess.Client"( ODAC).dll.

我接下来的故障排除步骤是使用 Reflector 调试来自 ODAC 代码的调用,并在强制发生此错误的同时获得更可靠的客户端跟踪。

我在尝试使用 ArrayBinding 插入 Oracle table 时遇到了同样的情况。

为 oracleCommand.ArrayBindCount 使用较小的数字似乎可以改善错误的频率(与您的一样),但不能完全改善。 解决方案是使用托管数据访问。我建议您获取最新的 ODP.NET,添加对 ManagedDataAccess 的引用并更改为:

使用 Oracle.ManagedDataAccess.Client;

使用 Oracle.ManagedDataAccess.Types;

这个问题在我的案例中已解决,无需更改代码中的任何内容。