【问题标题】:Getting exception "The provider is not compatible with the version of Oracle client" only when using NServiceBus pub/sub method仅在使用 NServiceBus pub/sub 方法时出现异常“提供程序与 Oracle 客户端的版本不兼容”
【发布时间】:2014-02-04 12:11:07
【问题描述】:

我有一个控制台应用程序项目(将移至 Windows 服务),它会根据 Oracle 数据库中的数据不断生成一些 XML 文件并将它们存储在一些文件夹中。它工作得很好。

新要求

现在我们收到了来自客户端的请求,我们必须将 XML 或其部分也发送到某些 Web 服务。

解决方案 1

创建另一个 Windows 服务,它将持续监视不同的文件夹并检索新创建的 XML 文件并对其执行操作。

这种方法的问题

  • 其他进程/用户可能随时读取文件
  • 无法跟踪已读取的文件,因为我无法将文件移动到任何地方,也无法重命名它以识别其已被读取
  • 用户可以在我的应用程序读取文件之前将文件移动到其他未知文件夹等

解决方案 2

在 app1 中使用NServiceBus 将生成的 XML 文件的数据放入 MSMQ。第二个应用程序将从那里检索它并做它必须做的任何事情。这似乎是个好主意,因为它会自动处理许多情况。

我在我的应用程序中使用StructureMap 进行依赖注入。我使用了PubSub 示例应用程序来获取帮助。我将我的原始 XML 生成应用程序配置为 Publisher。它适用于简单的场景,但是当我尝试将它与使用 VPN 访问远程 Oracle 数据库的实际生产代码一起使用时出现异常。当StructureMap 尝试创建我用作依赖项的对象时会发生异常。当代码尝试创建OracleConnection 对象时,在此对象链创建过程中会引发异常。最里面的异常说

The provider is not compatible with the version of Oracle client

此异常完全具有误导性,因为到目前为止我一直在成功使用相同的代码。当我最初使用具有最少配置的NServiceBus'Send 方法时,它甚至可以正常工作,但在我开始实施Publisher 模式时就开始发生。

目前我在发布者应用中的设置如下:

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
    <section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
    <section name="AuditConfig" type="NServiceBus.Config.AuditConfig, NServiceBus.Core" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>

  <UnicastBusConfig>
    <MessageEndpointMappings />
  </UnicastBusConfig>  

  <MessageForwardingInCaseOfFaultConfig ErrorQueue="error" />

  <AuditConfig QueueName="audit" />
</configuration>

端点配置

class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
    public void Init()
    {
        ConfigureStructureMap();
        ConfigureNServiceBus();
    }

    private void ConfigureStructureMap()
    {
        ObjectFactory.Configure(config =>
        {
            config.Scan(
                scan =>
                {
                    scan.TheCallingAssembly();
                    scan.Assembly("Business");
                    scan.WithDefaultConventions();
                }
                );

            config.For<ILogger>().Singleton().Use<LogManager>();
        });
    }

    private void ConfigureNServiceBus()
    {
        Configure.Serialization.Xml();

        //Disable transactions
        Configure.Transactions.Disable();

        Configure.With()
            .StructureMapBuilder(ObjectFactory.Container)
            .UseTransport<Msmq>();
    }
}

服务器端点

public class ServerEndpoint : IWantToRunWhenBusStartsAndStops
{
    public void Start()
    {
        //this code throws the exception
        var wpaXmlManager = ObjectFactory.GetInstance<ITaskSchedular>();
        wpaXmlManager.StartImport();
    }

    public void Stop() { }
}

你能告诉我我做错了什么吗?

【问题讨论】:

  • 您的 Oracle 客户端和服务器版本是什么?

标签: c# nservicebus


【解决方案1】:

一个可能的原因是交易升级。

你看,Publish 方法在 NServiceBus 订阅存储(默认为 RavenDB)中查找订阅者列表。这可能发生在与您的 Oracle 代码相同的工作单元中,然后该代码尝试加入同一个事务,可能导致升级为分布式事务。

您可能需要不同版本的 Oracle 客户端库来支持分布式事务。

话虽如此,在这种特定情况下,您可能可以安全地关闭与 NServiceBus 的事务 - 因为您正在使用在任何情况下都不是事务性的文件系统。

希望对您有所帮助。

【讨论】:

  • 好的。我只是通过调用 Configure.Transactions.Disable(); 来检查它。也是。同样的问题.. :( 我已经更新了我的问题以反映我在 ConfigureNServiceBus() 方法中所做的事情。
  • 你能帮忙吗?我被卡住了。
  • 你用 Oracle 做什么?
  • 我们的客户组织使用 Oracle 数据库存储他们的数据。我必须根据该 Oracle DB 中的某些表数据生成 XML 文档。
  • 能否在启动时缓存 Oracle DB 中的数据,然后将该缓存用作消息处理的一部分?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 2010-11-18
  • 2010-10-14
  • 2013-06-29
  • 1970-01-01
  • 2014-05-25
相关资源
最近更新 更多