C# “获取异常”;提供程序与Oracle客户端的版本不兼容;仅当使用NServiceBus发布/订阅方法时
我有一个控制台应用程序项目(将移动到windows服务),它根据Oracle数据库中的数据连续生成一些XML文件,并将它们存储在一些文件夹中。它工作得很好 新要求C# “获取异常”;提供程序与Oracle客户端的版本不兼容;仅当使用NServiceBus发布/订阅方法时,c#,nservicebus,C#,Nservicebus,我有一个控制台应用程序项目(将移动到windows服务),它根据Oracle数据库中的数据连续生成一些XML文件,并将它们存储在一些文件夹中。它工作得很好 新要求 public class ServerEndpoint : IWantToRunWhenBusStartsAndStops { public void Start() { //this code throws the exception var wpaXmlManager = Objec
public class ServerEndpoint : IWantToRunWhenBusStartsAndStops
{
public void Start()
{
//this code throws the exception
var wpaXmlManager = ObjectFactory.GetInstance<ITaskSchedular>();
wpaXmlManager.StartImport();
}
public void Stop() { }
}
现在,我们收到了客户机的请求,要求我们也将XML或其部分发送到某个web服务
解决方案1
创建另一个windows服务,它将继续监视不同的文件夹,检索新创建的XML文件并对其执行操作
这种方法的问题
- 另一个进程/用户可以随时读取该文件
- 无法跟踪已读取的文件,因为我无法将该文件移动到任何位置,也无法重命名该文件以标识其已被读取
- 在我的应用程序读取文件之前,用户可以将文件移动到其他未知文件夹,等等
NServiceBus
,将生成的XML文件的数据放置在MSMQ中。第二个应用程序将从那里检索它并执行它必须执行的任何操作。这似乎是个好主意,因为它可以自动处理许多情况
我正在应用程序中使用StructureMap
进行依赖注入。我使用PubSub
示例应用程序从中获取帮助。我将原始XML生成应用程序配置为Publisher
。它适用于简单的场景,但当我尝试将其与实际生产代码一起使用时,会遇到一个异常,该代码使用VPN访问远程Oracle db。当StructureMap
尝试创建我用作依赖项的对象时,会发生异常。在此对象链创建期间,当代码尝试创建OracleConnection
对象时,会引发异常。最内在的例外是
提供程序与Oracle客户端版本不兼容
这个例外完全是误导性的,因为到目前为止我一直在成功地使用相同的代码。它甚至在我最初使用配置最少的NServiceBus
“Send
方法时工作正常,但在我开始实现Publisher
模式时就开始出现了
当前我在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>();
}
}
EndpointConfig
<?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>();
}
}
class EndpointConfig:IConfigureThisEndpoint,AsA_发布者,IWantCustomInitialization
{
公共void Init()
{
ConfigureStructureMap();
配置服务总线();
}
私有void ConfigureStructureMap()
{
ObjectFactory.Configure(配置=>
{
配置扫描(
扫描=>
{
扫描。卡入总成();
扫描、组装(“业务”);
scan.WithDefaultConventions();
}
);
config.For().Singleton().Use();
});
}
私有void配置服务总线()
{
Configure.Serialization.Xml();
//禁用事务
Configure.Transactions.Disable();
用()配置
.StructureMapBuilder(ObjectFactory.Container)
.UseTransport();
}
}
ServerEndpoint
public class ServerEndpoint : IWantToRunWhenBusStartsAndStops
{
public void Start()
{
//this code throws the exception
var wpaXmlManager = ObjectFactory.GetInstance<ITaskSchedular>();
wpaXmlManager.StartImport();
}
public void Stop() { }
}
公共类ServerEndpoint:iwanttorunshenbusstartsandstops
{
公开作废开始()
{
//此代码引发异常
var wpaxmlmmanager=ObjectFactory.GetInstance();
wpaxmlmmanager.StartImport();
}
公共无效停止(){}
}
您能告诉我我做错了什么吗?一个可能的原因是交易升级 您可以看到,
Publish
方法在NServiceBus订阅存储中查找订阅服务器列表(默认情况下为RavenDB)。这可能发生在与Oracle代码相同的工作单元中,然后Oracle代码尝试登记到同一事务中,可能导致升级到分布式事务
您可能需要不同版本的Oracle客户端库来获得对分布式事务的支持
这就是说,在这种特定情况下,您可能会安全地关闭与NServiceBus的事务,因为您使用的文件系统在任何情况下都不是事务性的
希望有帮助。好的。我只是通过调用Configure.Transactions.Disable()来检查它;也同样的问题..:(我更新了我的问题,以反映我在ConfigureNServiceBus()中所做的工作)方法。你能帮忙吗?我被卡住了。你用Oracle做什么?我们的客户组织使用Oracle数据库作为他们的数据。我必须根据Oracle数据库中某些表的数据生成XML文档。你能在启动时缓存Oracle数据库中的数据,然后将该缓存用作消息处理的一部分吗?你的Oracle clie是什么nt和服务器版本?