【问题标题】:Issues with Oracle .NET DATA Provider - Looking for other optionOracle .NET 数据提供程序的问题 - 寻找其他选项
【发布时间】:2016-06-14 21:13:15
【问题描述】:

在我开始之前,我建议你深呼吸并理解,这是一个很长的问题,在单个上下文中有 3-4 个问题。所以阅读时要有耐心。 (如果您需要任何东西、代码示例或任何我正在认真寻找解决方案的东西,请在评论中写下)。

最近我一直在与一位客户合作,他希望在 Oracle 中拥有应用程序数据库。该应用程序基于 ASP.NET MVC 构建。

我们选择Oracle 11g express作为开发环境,客户已经确认了。我们决定使用支持 ORM (EF) 的 ODAC 32bit .NET Provider。我们首先进行了一个实施 CRUD 操作的试验案例,一切正常。然后我们开始开发实际的客户需求。在 2-3 个月内,产品已准备好交付。所以到目前为止,在 ASP.NET 和 Oracle 11g 上一切正常。当我们进行部署和 UAT 时,我们了解到客户正在为他现有的 ERP 使用 oracle 9i,这与我们开发的版本不匹配。因此,我们在 Internet 上搜索以验证同一 ODAC 提供程序是否与 Oracle 9i 兼容。我们找到了提到它与 Oracle 9i 兼容的参考资料。

我们刚刚将数据库迁移到Oracle 9i服务器,相应地更改EF模型,发现以下问题:

1.交易未自动提交!

using (TransactionScope transaction = new TransactionScope())
{
    // some code written here
}

相同的代码在 11g 中运行,但在移至 Oracle 9i 时停止运行。在 using 语句完成后,事务不会自动提交。我们故意在 using 块中写了transaction.commit();,它开始工作了。

这是预期的行为吗?

2。 VARCHAR2 数据类型和 ODP NET 提供程序存在问题。 我们在以Varchar2 和其他数据库类型作为参数的数据库中创建了一些存储过程。在使用 ADO.NET 样式 (OracleConnection, OracleCommand 和 OracleParameter) 访问这些存储过程时,我们了解到具有 VARCHAR2 数据类型的参数有时会截断数据,即使数据传递给参数的大小小于给定的表格列。它只是从末尾随机删除字符数。 Problem is also logged here in oracle forum

我们无法找到解决方案。

3.内联查询大小限制(字符数)。 为了解决 #2 中提到的问题,我们意识到我们应该将这些存储过程转换为内联查询并使用 ADO.NET 调用那些(学生时代编码的旧风格)!我们把我们所有的存储过程都转换成行脚本,写成如下

OracleCommand command=new OracleCommand("Select * from something",Connection);

并对其他 DML 语句使用相同的技术。现在一切正常,我们执行了 UAT 并让应用程序上线。 10-15 天后,我们发现了奇怪的问题。如果查询(内联查询)的大小超过 4000 个字符,则 Oracle 服务器会抛出异常,指出“查询太长而无法执行”(我不记得确切的异常或消息,但它与我所写的相似) .拿了开发环境的样例数据,通过代码调试,发现SQL查询的长度太长了,超过32000到64000个字符! 我们知道这个问题的解决方案是相同的“如果我们能够以某种方式正确调用存储过程!”但我们不能,因为我们别无选择。

作为一种解决方案,我们在数据库中重新创建了那些存储过程,并将这些存储过程称为内联!

OracleCommand command=new OracleCommand("BEGIN ProceduretoCall(Param1,Param2); END;",Connection);

从那时起它就开始工作了。

考虑到以上问题,

  1. 我无法以通常的方式从 ASP.NET 调用存储过程 (CommandType.StoredProcedure) #problem-1 在上面
  2. 插入或更新后,我无法从存储过程返回任何数据或标量值或返回值。上面的#problem-3
  3. 我无法在代码级别使用事务。 (它一直说,分布式事务已初始化,但实际上我根本没有分布式事务!)

为什么要在上线后结束所有上述内容? 我已经解决了一个月,一个接一个地解决了 Oracle 的问题,这几乎是噩梦,这让我思考

ODP.NET/ODAC工具真的靠谱吗?

如果不是,那么根据您的经验,我可以选择哪些其他选择? (请注意 ODBC 在 Oracle 9i 中也存在类似问题)。

我更有可能在下周从事类似的项目,我想这次我想以更好的方法做好准备。

【问题讨论】:

  • 不支持 Oracle 9i。不应针对它开发新的应用程序。
  • 你应该把你的问题分成几部分。这个问题无法回答。

标签: .net oracle oracle11g odp.net oracle9i


【解决方案1】:

我强烈建议您将您的每一个观点单独作为一个单独的问题。每个问题都是具体的,并且有自己的问题,如果保持直截了当,这将是一团糟。

第二,我同意这个评论。甚至 2003 年发布的 Oracle 10gR1 也不受支持。也许你需要承担一些责任,不要提前问这个问题,但我也不认为你也声明他们将使用受支持的 oracle 版本是不合理的。

那是说我会快速刺伤:

  1. TransactionScope 从不自动提交。您需要添加 transaction.Complete()。唯一的意外行为是 WAS 之前提交的。

  2. 引用的文章提到该问题在重新编译 oracle 过程时得到解决,并指出了解决该问题的 oracle 补丁集。如果是这种情况,我不认为这是 odp.net 问题。如果您愿意,您可以粘贴 proc 签名和添加参数的方式,看看是否有一些 tweeks 可以尝试。但同样,我将作为一个单独的问题发布。

3.2 - 我不确定你是如何返回标量的 - 你需要一个参数上的 refcursor,我不确定创建一个匿名块会如何改变它。我再次认为您需要发布更多代码,特别是您如何发送参数。

3.3 - 当事务包含多个连接时,TransactionScope 会自动从本地事务转换为分布式连接,即使它们指向同一个数据库。但是,我认为直到 11g 才支持此功能,并且以前所有事务都以分布式开始。但是,我不确定 9i 是否有这个概念,这可能解释了您所看到的奇怪的自动提交。

在过去的 7 年里,ODP.net 对我来说一直是完全可靠的。也就是说,我总是针对受支持的 oracle 版本运行它,并为该版本设置了合理的最新补丁。

【讨论】:

  • 我完全理解并有事件考虑将这些问题分成不同的问题,但随后无法获得上下文......正如你看到后面的问题相互关联......不支持 Oracle 9i ?它受支持,但没有按预期工作。
  • 关于其他 cmets,TransactionScope 会像微软所说的那样自动提交,这对我来说一直适用于 MSSQL。在参考文章中你可以再去检查一下,也有像我这样的人即使重新编译包也无法解决这个问题! (在我的情况下,我没有包我不介意重新编译我的程序)。我如何返回标量?使用我在 MSSQL 中所做的返回值,但由于存储过程停止工作,我别无选择。
  • 我应该同意并交叉检查第 3.3 点(我确实对同一个数据库有多个连接),所以这可能是原因之一。感谢您指出这一点!
  • 让我详细说明一下,在我上面发布的链接中,请参阅该用户“gdarling - oracle”的评论,他提到将数据库版本从 9207 修补到 9208 可以解决问题。在我的例子中,数据库版本是 9206。客户在这个版本上开发了一个巨大的 ERP,他们在过去的 20 年中从未升级过他们的数据库版本,他们也没有准备好冒险改变他们的版本。他们上一次让他们的系统离线是在 2003 年,只有几分钟!所以升级数据库版本也不是我的选择!
  • 我 100% 确定 TransactionScope 不会自动提交。你必须告诉我哪里不需要 scope.Complete()。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2011-01-31
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多