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

时间:2015-02-14 02:05:38

标签: oracle odp.net oracle12c odac

这是我们的环境:

.Net版本:4.5

数据库:Oracle 12.1.0.2(odp.net)

我们正在使用LLBL"适配器"但我认为这与问题无关

LLBLGen专业版:4.1

Llbl Gen Pro Runtime: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));

当数据库被多个并行插入时遇到困难时,我们会收到以下错误,并且插入调用永远不会从数据库返回。

  • WG_6.Index_586.TVD:在执行操作查询期间捕获到异常:ORA-24381:数组DML中的错误

ORA-12592:TNS:坏包

ORA-12592:TNS:坏包

ORA-12592:TNS:坏包

ORA-12592:TNS:坏包

ORA-03111:在通讯频道收到中断

ORA-03111:在通讯频道收到中断

ORA-03111:在通讯频道收到中断

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

在Toad的Waits选项卡下,有以下消息: “等待SQL * Net从客户端获取更多数据 - 等待X秒,到目前为止”并且X一直在递增,直到我们达到数据库超时。

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

几点说明:

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

  2. 从错误消息(ORA-12592:TNS:错误数据包)中,似乎问题可能出在客户端上,并且可能与" Oracle.DataAccess.Client"中的代码有关。 (ODAC)dll。

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

1 个答案:

答案 0 :(得分:0)

尝试使用ArrayBinding插入Oracle表时,情况相同。

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

使用Oracle.ManagedDataAccess.Client;

使用Oracle.ManagedDataAccess.Types;

这个问题在我的情况下解决了,无需更改代码中的任何内容。