NServiceBus Saga持久性

NServiceBus Saga持久性,nservicebus,Nservicebus,我们有一个配置为运行sagas的NServiceBus服务。有了内存持久性,一切都可以正常运行。尝试将配置文件更改为NServiceBus.Integration时,启动服务时出错 端点配置: public class MyEndpoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization { private IContainer _container; public void Init()

我们有一个配置为运行sagas的NServiceBus服务。有了内存持久性,一切都可以正常运行。尝试将配置文件更改为NServiceBus.Integration时,启动服务时出错

端点配置:

public class MyEndpoint : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
    private IContainer _container;

    public void Init()
    {
        log4net.Config.XmlConfigurator.Configure();
        SetupStructureMap();

        Configure.With()
            .Log4Net()
            .StructureMapBuilder(_container)
            .Sagas()
            .XmlSerializer();
    }

    private void SetupStructureMap()
    {
        [...]
    }
}
错误消息:

    FATAL 2012-01-18 11:11:52,197  2640ms GenericHost            Start              - FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

      * Database was not configured through Database method.
     ---> System.ArgumentException: The number of generic arguments provided doesn't equal the arity of the generic type definition.
    Parameter name: instantiation
       at System.RuntimeType.MakeGenericType(Type[] instantiation)
       at FluentNHibernate.Automapping.AutoMapManyToMany.GetInverseProperty(PropertyInfo property)
       at FluentNHibernate.Automapping.AutoMapManyToMany.MapsProperty(PropertyInfo property)
       at FluentNHibernate.Automapping.AutoMapper.TryToMapProperty(ClassMappingBase mapping, PropertyInfo property, IList`1 mappedProperties)
       at FluentNHibernate.Automapping.AutoMapper.MapEverythingInClass(ClassMappingBase mapping, Type entityType, IList`1 mappedProperties)
       at FluentNHibernate.Automapping.AutoMapper.MergeMap(Type classType, ClassMappingBase mapping, IList`1 mappedProperties)
       at FluentNHibernate.Automapping.AutoMapper.Map(Type classType, List`1 types)
       at FluentNHibernate.Automapping.AutoPersistenceModel.AddMapping(Type type)
       at FluentNHibernate.Automapping.AutoPersistenceModel.CompileMappings()
       at FluentNHibernate.Cfg.AutoMappingsContainer.Apply(Configuration cfg)
       at FluentNHibernate.Cfg.MappingConfiguration.Apply(Configuration cfg)
       at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration()
       --- End of inner exception stack trace ---
       at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration()
       at NServiceBus.SagaPersisters.NHibernate.Config.Internal.SessionFactoryBuilder.UpdateDatabaseSchemaUsing(FluentConfiguration fluentConfiguration)
       at NServiceBus.SagaPersisters.NHibernate.Config.Internal.SessionFactoryBuilder.Build(IDictionary`2 nhibernateProperties, Boolean updateSchema)
       at NServiceBus.ConfigureNHibernateSagaPersister.NHibernateSagaPersister(Configure config, IDictionary`2 nhibernateProperties, Boolean autoUpdateSchema)
       at NServiceBus.ConfigureNHibernateSagaPersister.NHibernateSagaPersisterWithSQLiteAndAutomaticSchemaGeneration(Configure config)
       at NServiceBus.Host.Internal.ProfileHandlers.IntegrationProfileHandler.NServiceBus.IHandleProfile.ProfileActivated()
       at NServiceBus.Host.Internal.ProfileManager.<ActivateProfileHandlers>b__14(IHandleProfile hp)
       at System.Collections.Generic.List`1.ForEach(Action`1 action)
       at NServiceBus.Host.Internal.ProfileManager.ActivateProfileHandlers()
       at NServiceBus.Host.Internal.GenericHost.Start()

      * Database was not configured through Database method.
FATAL 2012-01-18 11:11:52197 2640ms GenericHost开始-FluentNHibernate.Cfg.FluentConfigurationException:创建SessionFactory时使用了无效或不完整的配置。有关详细信息,请检查潜在原因集合和InnerException。
*未通过数据库方法配置数据库。
--->System.ArgumentException:提供的泛型参数数量不等于泛型类型定义的arity。
参数名称:实例化
位于System.RuntimeType.MakeGenericType(类型[]实例化)
在FluentNHibernate.Automapping.AutoMapManyToMany.GetInverseProperty(PropertyInfo属性)
位于FluentNHibernate.Automapping.AutoMapManyToMany.MapsProperty(PropertyInfo属性)
位于FluentNHibernate.Automapping.AutoMapper.TryToMapProperty(ClassMappingBase映射、PropertyInfo属性、IList`1 mappedProperties)
位于FluentNHibernate.Automapping.AutoMapper.mapeverythingClass(ClassMappingBase映射,类型entityType,IList`1 mappedProperties)
在FluentNHibernate.Automapping.AutoMapper.MergeMap(类型classType,ClassMappingBase mapping,IList`1 mappedProperties)
在FluentNHibernate.Automapping.AutoMapper.Map(类型classType,列表'1类型)
位于FluentNHibernate.Automapping.AutoPersistenceModel.AddMapping(类型)
在FluentNHibernate.Automapping.AutoPersistenceModel.CompileMappings()中
在FluentNHibernate.Cfg.AutoMappingsContainer.Apply(配置Cfg)中
在FluentNHibernate.Cfg.MappingConfiguration.Apply(配置Cfg)中
在FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration()中
---内部异常堆栈跟踪的结束---
在FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration()中
位于NServiceBus.SagaPersisters.NHibernate.Config.Internal.SessionFactoryBuilder.UpdateDatabaseSchemaUsing(FluentConfiguration FluentConfiguration)
位于NServiceBus.SagaPersisters.NHibernate.Config.Internal.SessionFactoryBuilder.Build(IDictionary`2 nhibernateProperties,布尔更新schema)
在NServiceBus.configurenhibernatesagpersister.nhibernatesagpersister(配置配置,IDictionary`2 nhibernateProperties,布尔自动更新架构)
在NServiceBus.ConfigureNHibernateSagaPersister.nHibernateSAgaPersisterWithSQLite和AutomaticSchemaGeneration(配置配置)
位于NServiceBus.Host.Internal.profileHandler.IntegrationProfileHandler.NServiceBus.IHandleProfile.ProfileActivated()处
位于NServiceBus.Host.Internal.ProfileManager.b__14(IHandleProfile hp)
at System.Collections.Generic.List`1.ForEach(操作`1操作)
在NServiceBus.Host.Internal.ProfileManager.ActivateProfileHandlers()上
在NServiceBus.Host.Internal.generihost.Start()处
*未通过数据库方法配置数据库。
配置文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
        <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
        <section name="MsmqSubscriptionStorageConfig" type="NServiceBus.Config.MsmqSubscriptionStorageConfig,NServiceBus.Core" />
    </configSections>
    <MsmqTransportConfig InputQueue="MyQueue" ErrorQueue="MyQueueError" NumberOfWorkerThreads="1" MaxRetries="5" />

    <UnicastBusConfig>
        <MessageEndpointMappings>
            <add Messages="My.MessageContracts" Endpoint="MyQueue" />
        </MessageEndpointMappings>
    </UnicastBusConfig>
    <log4net debug="false">
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
            <file value="C:\Log\My.log" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="10" />
            <maximumFileSize value="10MB" />
            <staticLogFileName value="true" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n" />
            </layout>
        </appender>
        <root>
            <level value="INFO" />
            <appender-ref ref="RollingLogFileAppender" />
        </root>
    </log4net>
</configuration>

看起来您在配置中缺少以下内容,它位于示例中OrderService的app.config中:

<section name="DBSubscriptionStorageConfig" type="NServiceBus.Config.DBSubscriptionStorageConfig, NServiceBus.Core" />
<section name="NHibernateSagaPersisterConfig" type="NServiceBus.Config.NHibernateSagaPersisterConfig, NServiceBus.Core" />

<DBSubscriptionStorageConfig>
    <NHibernateProperties>
      <add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider"/>
      <add Key="connection.driver_class" Value="NHibernate.Driver.SQLite20Driver"/>
      <add Key="connection.connection_string" Value="Data Source=.\Subscriptions.sqlite;Version=3;New=True;"/>
      <add Key="dialect" Value="NHibernate.Dialect.SQLiteDialect"/>
    </NHibernateProperties>
  </DBSubscriptionStorageConfig>

<NHibernateSagaPersisterConfig>
    <NHibernateProperties>
      <add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider"/>
      <add Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver"/>
      <add Key="connection.connection_string" Value="Server=localhost;initial catalog=NServiceBus;Integrated Security=SSPI"/>
      <add Key="dialect" Value="NHibernate.Dialect.MsSql2000Dialect"/>
    </NHibernateProperties>
  </NHibernateSagaPersisterConfig>

正如Andreas所提到的,问题在于使用NHibernate/Fluent NHibernate持久化SagaData类

总结一下所有错误的地方:

  • 为了使用概要文件NServicebus。集成,您需要添加对SQLite的引用(使用NuGet)
  • 要使用概要文件NServiceBus.生产,您需要在app.config中设置与数据库的连接,如下所示
  • 为了使用这两个配置文件,您的SagaData类必须遵守NHibernate的规则:
    • 所有属性都必须是虚拟的
    • 该类不能被密封
    • 所有属性的类型也是如此

所有这些都是针对NServiceBus 2.6的。在3.0中,即现在的Beta6中,他们使用RavenDB,而不与NHibernate或SQLite绑定。从2.6到3.0的过渡是如何进行的,我还不知道,但我认为这是我们进行该项目的方式。

顺便说一下,我们正在运行NServiceBus 2.6。您是否可以包含您的配置文件,以便我们可以看到您包含了所有内容?配置文件现在已添加。似乎自动映射失败,你能添加你的saga实体类吗?看起来我们在设计Sagaadata类时做了所有错误的事情。成员不是虚拟的,许多成员属于NServicebus无法处理的类型。明天我们将对此进行更多的研究,然后在这里返回更新。