Cómo garantizar un buen rendimiento con MassTransit Saga que agrega un elemento a una IList persistente de NHibernate

Tengo una saga que tiene 3 estados -

    public static State Initial { get; set; }
    public static State ReceivingRows { get; set; }
    public static State Completed { get; set; }

Pasa de Inicial a Filas de recepción cuando recibe un BofMessage (donde Bof = Comienzo del archivo). Después del BofMessage, recibe una gran cantidad de RowMessages donde cada uno describe una fila en un archivo sin formato. Una vez que se envían todos los RowMessage, se envía un EofMessage y el estado cambia a Completado. observar -

static void DefineSagaBehavior()
{
    Initially(When(ReceivedBof)
        .Then((saga, message) => saga.BeginFile(message))
        .TransitionTo(ReceivingRows));

    During(ReceivingRows, When(ReceivedRow)
        .Then((saga, message) => saga.AddRow(message)));

    During(ReceivingRows, When(ReceivedRowError)
        .Then((saga, message) => saga.RowError(message)));

    During(ReceivingRows, When(ReceivedEof)
        .Then((saga, message) => saga.EndFile(message))
        .TransitionTo(Completed));
}

public override void OnAddRow(ParcelRowMessage message)
{
    // ensure isCauvReturned is "Y"
    var fields = message.Value;
    var isCauvReturned = fields[33] == "Y";
    if (!isCauvReturned)
        return;

    // add row with just parcel number
    var parcelNumber = fields[1];
    var row = parcelNumber;
    _rows.Add(row);
}

Esto funciona excepto que tiene un rendimiento de n-cuadrado. Investigar con NHProf revela que cada fila agregada hace que la lista completa de filas para ser:

A) seleccionado de la base de datos

B) eliminado de la base de datos

C) reinsertado en la base de datos.

Esto me parece muy mal comportamiento. Todo lo que se necesita para agregar una fila es… bueno, ¡agregar una sola fila a la base de datos! La operación de agregar es literalmente lo único que estoy haciendo con la lista de filas. Esto no se escala cuando tenemos 10,000 elementos en la lista.

¿Alguien sabe como darle a esta saga un comportamiento de rendimiento más cuerdo?

Por cierto, así es como se asigna IList si lo necesita:

        HasMany(x => x.Rows)
            .Table("OwnerHistorySagaRow")
            .KeyColumn("CorrelationId")
            .Element("Row")
            .Cascade.AllDeleteOrphan();

¡Gracias!

preguntado el 22 de mayo de 12 a las 20:05

2 Respuestas

Sé que este es un elemento muerto, pero aquí está la respuesta real para hacer que una bolsa funcione correctamente.

Bag(x => x.Rows, c =>
{
    c.Key(k =>
    {
        k.Column("RowCorrelationId");
        k.ForeignKey("FK_State_Row");
        k.NotNullable(true);
    });
    c.Fetch(CollectionFetchMode.Join);
    c.Lazy(CollectionLazy.NoLazy);
    c.Cascade(Cascade.All);
}, r => r.OneToMany());

El tipo de clase para Rows is IList<Row>.

Respondido 25 Feb 15, 15:02

contestado el 23 de mayo de 12 a las 00:05

Investigué esto, pero me temo que no me da suficientes detalles para continuar. ¿Podría dar una respuesta más específica? - bryan edds

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.