Ordenación lógica y física
Los mensajes de una cola pueden estar (dentro de cada nivel de prioridad) en orden físico o lógico.
El orden físico es el orden en el que los mensajes llegan a una cola. El orden lógico es cuando todos los mensajes y segmentos dentro de un grupo están en su secuencia lógica, unos a continuación de otros, en la posición determinada por la posición física del primer elemento perteneciente al grupo.
- Los grupos pueden llegar a un destino en momentos similares procedentes de aplicaciones diferentes, por lo tanto, pierden cualquier orden físico diferenciado.
- Incluso dentro de un mismo grupo, los mensajes pueden perder el orden debido a la redirección o el retraso de algunos de los mensajes del grupo.
Por ejemplo, el orden lógico podría parecerse a la figura Figura 1:

- Mensaje A (no en un grupo)
- Mensaje lógico 1 del grupo Y
- Mensaje lógico 2 del grupo Y
- Segmento 1 de (último) mensaje lógico 3 del grupo Y
- (Último) segmento 2 del (último) mensaje lógico 3 del grupo Y
- Mensaje lógico 1 del grupo Z
- (Último) mensaje lógico 2 del grupo Z
- Mensaje B (no en un grupo)

- Mensaje A (no en un grupo)
- Mensaje lógico 1 del grupo Y
- Mensaje lógico 2 del grupo Z
- Mensaje lógico 2 del grupo Y
- Segmento 1 de (último) mensaje lógico 3 del grupo Y
- (Último) segmento 2 del (último) mensaje lógico 3 del grupo Y
- Mensaje lógico 1 del grupo Z
- Mensaje B (no en un grupo)
Al obtener mensajes, puede especificar MQGMO_LOGICAL_ORDER para recuperar mensajes en orden lógico en lugar del orden físico.
Si emite una llamada MQGET con MQGMO_BROWSE_FIRST y MQGMO_LOGICAL_ORDER, las llamadas MQGET subsiguientes con MQGMO_BROWSE_NEXT deben también especificar MQGMO_LOGICAL_ORDER. Por el contrario, si la llamada MQGET con MQGMO_BROWSE_FIRST no especifica MQGMO_LOGICAL_ORDER, tampoco deben especificarlo las llamadas MQGET subsiguientes con MQGMO_BROWSE_NEXT.
La información de grupo y segmento que el gestor de colas retiene para las llamadas MQGET que examinan mensajes de la cola está separada de la información de grupo y segmento que el gestor de colas retiene para las llamadas MQGET que eliminan mensajes de la cola. Cuando especifica MQGMO_BROWSE_FIRST, el gestor de colas pasa por alto la información de grupo y de segmento para el examen y explora la cola como si no hubiera ningún grupo actual y ningún mensaje lógico actual.
MsgSeqNumber establecido en 1 (para
encontrar el primer mensaje del grupo siguiente) devuelve de nuevo el
primer mensaje del grupo ya examinado. Esto podría ocurrir de forma
inmediata, o después de varias llamadas MQGET (si hay grupos intermedios).- Utilice el primer descriptor para examinar solamente el primer mensaje de cada grupo.
- Utilice el segundo descriptor para examinar solamente los mensajes de un grupo específico.
- Utilice las opciones MQMO_* para desplazar el segundo cursor de examen a la posición del primer cursor de examen, antes de examinar los mensajes del grupo.
- No utilice el examen de MQGMO_BROWSE_NEXT más allá del final de un grupo.
Para la mayoría de aplicaciones, probablemente eligirá el orden lógico o físico al examinar. Pero si desea conmutar entre estas modalidades, recuerde que cuando emite por primera vez un examen con MQGMO_LOGICAL_ORDER, se establece la posición del cursor dentro de la secuencia lógica.
Si en este momento el primer elemento del grupo no está presente, se considera que el grupo en el que se encuentra no forma parte de la secuencia lógica.
Una vez que el cursor de examen está dentro de un grupo, puede continuar dentro del mismo grupo, incluso si se elimina el primer mensaje. Pero inicialmente nunca puede pasar a un grupo utilizando MQGMO_LOGICAL_ORDER cuando el primer elemento no está presente.
- MQPMO_LOGICAL_ORDER
- La opción MQPMO indica al gestor de colas cómo la aplicación coloca los mensajes en grupos y segmentos de mensajes lógicos. Sólo se puede
especificar en la llamada MQPUT; no es válida en la llamada MQPUT1.Si se especifica MQPMO_LOGICAL_ORDER, indica que la aplicación utiliza llamadas MQPUT sucesivas para:
- Poner los segmentos de cada mensaje lógico en el orden de desplazamiento de segmento creciente, empezando desde 0, sin huecos.
- Poner todos los segmentos en un mensaje lógico antes de poner los segmentos en el siguiente mensaje lógico.
- Poner los mensajes lógicos de cada grupo de mensajes en el orden de número de secuencia de mensaje creciente, empezando desde 1, sin huecos. IBM MQ incrementa automáticamente el número de secuencia de mensaje.
- Poner todos los mensajes lógicos en un grupo de mensajes antes de poner los mensajes lógicos en el siguiente grupo de mensajes.
Debido a que la aplicación ha indicado al gestor de colas cómo coloca mensajes en grupos y segmentos de mensajes lógicos, la aplicación no necesita mantener y actualizar la información de grupo y de segmento referente a cada llamada MQPUT, pues el gestor de colas mantiene y actualiza esta información. En concreto, significa que la aplicación no necesita establecer los campos
GroupId,MsgSeqNumberyOffseten MQMD, porque el gestor de colas establece estos campos en los valores adecuados. La aplicación sólo debe establecer el campoMsgFlagsen MQMD, para indicar cuándo los mensajes pertenecen a grupos o son segmentos de mensajes lógicos, y para indicar el último mensaje de un grupo o último segmento de un mensaje lógico.Una vez iniciado un grupo de mensajes o un mensaje lógico, las llamadas MQPUT posteriores deben especificar los distintivos MQMF_* apropiados en
MsgFlagsen MQMD. Si la aplicación intenta colocar un mensaje que no está en un grupo cuando hay un grupo de mensajes sin terminar, o bien coloca un mensaje que no es un segmento cuando hay un mensaje lógico sin terminar, la llamada falla y devuelve el código de razón MQRC_INCOMPLETE_GROUP o MQRC_INCOMPLETE_MSG, según corresponda. Sin embargo, el gestor de colas retiene la información sobre el grupo de mensajes actual o mensaje lógico actual, y la aplicación puede terminarlos enviando un mensaje (posiblemente sin datos de mensaje de aplicación) especificando MQMF_LAST_MSG_IN_GROUP o MQMF_LAST_SEGMENT según corresponda, antes de emitir de nuevo la llamada MQPUT para colocar el mensaje que no está en el grupo o no es un segmento.La Figura 2 muestra las combinaciones de opciones y distintivos que son válidos, y los valores de los camposGroupId,MsgSeqNumberyOffsetque el gestor de colas utiliza en cada caso. Las combinaciones de opciones y distintivos que no aparecen en la tabla no son válidas. Las columnas de la tabla tienen los significados siguientes. "Cualquiera de los dos" significa Sí o No:- LOG ORD
- Indica si la opción MQPMO_LOGICAL_ORDER se ha especificado en la llamada.
- MIG
- Indica si la opción MQMF_MSG_IN_GROUP o MQMF_LAST_MSG_IN_GROUP se ha especificado en la llamada.
- SEG
- Indica si la opción MQMF_SEGMENT o MQMF_LAST_SEGMENT se ha especificado en la llamada.
- SEG OK
- Indica si la opción MQMF_SEGMENTATION_ALLOWED se ha especificado en la llamada.
- Cur grp
- Indica si existe un grupo de mensajes actual antes de la llamada.
- Cur log msg
- Indica si existe un mensaje lógico actual antes de la llamada.
- Otras columnas
- Muestra los valores que utiliza el gestor de colas. "Anterior" denota el valor utilizado para el campo en el mensaje anterior para el descriptor de contexto de cola.
Tabla 1. Opciones de MQPUT relacionadas con los mensajes de grupos y los segmentos de mensajes lógicos Opciones especificadas Opciones especificadas Opciones especificadas Opciones especificadas Estado de grupo y mensaje lógico antes de la llamada Estado de grupo y mensaje lógico antes de la llamada Valores que utiliza el gestor de colas Valores que utiliza el gestor de colas Valores que utiliza el gestor de colas LOG ORD MIG SEG SEG OK Cur grp Cur log msg GroupId MsgSeqNumber Offset Sí No No No No No MQGI_NONE 1 0 Sí No No Sí No No Nuevo ID de grupo 1 0 Sí No Sí Cualquiera de los dos No No Nuevo ID de grupo 1 0 Sí No Sí Cualquiera de los dos No Sí ID de grupo anterior 1 Desplazamiento anterior + longitud de segmento anterior Sí Sí Cualquiera de los dos Cualquiera de los dos No No Nuevo ID de grupo 1 0 Sí Sí Cualquiera de los dos Cualquiera de los dos Sí No ID de grupo anterior Número de secuencia anterior + 1 0 Sí Sí Sí Cualquiera de los dos Sí Sí ID de grupo anterior Número de secuencia anterior Desplazamiento anterior + longitud de segmento anterior No No No No Cualquiera de los dos Cualquiera de los dos MQGI_NONE 1 0 No No No Sí Cualquiera de los dos Cualquiera de los dos ID de grupo nuevo si MQGI_NONE, en otro caso, valor en campo 1 0 No No Sí Cualquiera de los dos Cualquiera de los dos Cualquiera de los dos ID de grupo nuevo si MQGI_NONE, en otro caso, valor en campo 1 Valor en campo No Sí No Cualquiera de los dos Cualquiera de los dos Cualquiera de los dos ID de grupo nuevo si MQGI_NONE, en otro caso, valor en campo Valor en campo 0 No Sí Sí Cualquiera de los dos Cualquiera de los dos Cualquiera de los dos ID de grupo nuevo si MQGI_NONE, en otro caso, valor en campo Valor en campo Valor en campo Nota:- MQPMO_LOGICAL_ORDER no es válido en la llamada MQPUT1.
- Para el campo
MsgId, el gestor de colas genera un nuevo identificador de mensaje si se especifica MQPMO_NEW_MSG_ID o MQMI_NONE; en otro caso, utiliza el valor contenido en el campo. - Para el campo
CorrelId, el gestor de colas genera un nuevo identificador de correlación si se especifica MQPMO_NEW_CORREL_ID; en otro caso, utiliza el valor contenido en el campo.
Cuando se especifica MQPMO_LOGICAL_ORDER, el gestor de colas requiere que todos los mensajes de un grupo y segmentos de un mensaje lógico se coloquen con el mismo valor en el campo
Persistencede MQMD, es decir, todos deben ser persistentes, o todos deben ser no persistentes. Si esta condición no se cumple, la llamada MQPUT falla y devuelve el código de razón MQRC_INCONSISTENT_PERSISTENCE.La opción MQPMO_LOGICAL_ORDER afecta a las unidades de trabajo de la manera siguiente:- Si el primer mensaje físico de un grupo o mensaje lógico se coloca dentro de una unidad de trabajo, todos los demás mensajes físicos del grupo o mensaje lógico se deben colocar dentro de una unidad de trabajo, si se utiliza el mismo descriptor de contexto de cola. Sin embargo, no es necesario colocarlos dentro de la misma unidad de trabajo, lo que permite que un grupo de mensajes o un mensaje lógico que conste de muchos mensajes físicos se pueda repartir entre dos o más unidades de trabajo consecutivas para el descriptor de contexto de cola.
- Si el primer mensaje físico de un grupo o mensaje lógico no se coloca dentro de una unidad de trabajo, ninguno de los demás mensajes físicos del grupo o mensaje lógico se puede colocar dentro de una unidad de trabajo, si se utiliza el mismo descriptor de contexto de cola.
Cuando se especifica MQPMO_LOGICAL_ORDER, el MQMD que se proporciona en la llamada MQPUT no debe ser menor que MQMD_VERSION_2. Si esta condición no se cumple, la llamada falla y devuelve el código de razón MQRC_WRONG_MD_VERSION.
Si MQPMO_LOGICAL_ORDER no se especifica, los mensajes de grupos y los segmentos de mensajes lógicos se pueden colocar en cualquier orden, y no es necesario colocar grupos de mensajes completos o mensajes lógicos completos. Corresponde a la aplicación asegurarse de que los campos
GroupId,MsgSeqNumber,OffsetyMsgFlagstengan valores apropiados.Utilice esta técnica para reiniciar un grupo de mensajes o mensaje lógico situado en el medio, después de producirse un error del sistema. Cuando se reinicia el sistema, la aplicación puede establecer los campos
GroupId,MsgSeqNumber,Offset,MsgFlagsyPersistenceen los valores apropiados y luego emitir la llamada MQPUT con MQPMO_SYNCPOINT o MQPMO_NO_SYNCPOINT establecido según convenga, pero sin especificar MQPMO_LOGICAL_ORDER. Si esta llamada es satisfactoria, el gestor de colas conserva la información de grupo y segmento, y las llamadas MQPUT posteriores que utilizan ese descriptor de contexto de cola pueden especificar MQPMO_LOGICAL_ORDER en la forma habitual.La información de grupo y segmento que el gestor de colas retiene para la llamada MQPUT está separada de la información de grupo y segmento que retiene para la llamada MQGET.
Para cualquier descriptor de contexto de cola determinado, la aplicación puede combinar llamadas MQPUT que especifican MQPMO_LOGICAL_ORDER con llamadas MQPUT que no lo hacen, pero tenga en cuenta los puntos siguientes:- Si no se especifica MQPMO_LOGICAL_ORDER, cada llamada MQPUT satisfactoria hace que el gestor de colas establezca la información de grupo y de segmento para el descriptor de cola en los valores especificados por la aplicación, sustituyendo la información de segmento y segmento existente retenida por el gestor de colas para el descriptor de cola.
- Si no se especifica MQPMO_LOGICAL_ORDER, la llamada no fallará si
existe un grupo de mensajes o un mensaje lógico actual; la llamada podría tener
éxito y devolver el código de terminación MQCC_WARNING. El cuadro 2 muestra los distintos casos que pueden darse. En estos casos, si el código de terminación no es
MQCC_OK, el código de razón es uno de los siguientes (según corresponda):
- MQRC_INCOMPLETE_GROUP
- MQRC_INCOMPLETE_MSG
- MQRC_INCONSISTENT_PERSISTENCE
- MQRC_INCONSISTENT_UOW
Nota: El gestor de colas no comprueba la información de grupo y segmento para la llamada MQPUT1 .
Tabla 2. Resultado cuando la llamada MQPUT o MQCLOSE no es coherente con la información de grupo y segmento La llamada actual es La llamada anterior era MQPUT con MQPMO_LOGICAL_ORDER La llamada anterior era MQPUT sin MQPMO_LOGICAL_ORDER MQPUT con MQPMO_LOGICAL_ORDER MQCC_FAILED MQCC_FAILED MQPUT sin MQPMO_LOGICAL_ORDER MQCC_WARNING MQCC_OK MQCLOSE con un grupo o mensaje lógico sin terminar MQCC_WARNING MQCC_OK Para las aplicaciones que colocan mensajes y segmentos en orden lógico, especifique MQPMO_LOGICAL_ORDER, pues la opción más sencilla de utilizar. Esta opción hace que la aplicación no tenga que gestionar la información de grupo y segmento, pues el gestor de colas lo hace en su lugar. Sin embargo, es posible que las aplicaciones especializadas necesiten más control que el proporcionado por la opción MQPMO_LOGICAL_ORDER, lo que se puede lograr no especificando dicha opción; si lo hace, debe asegurarse de que los campos
GroupId,MsgSeqNumber,OffsetyMsgFlagsen MQMD se hayan establecido correctamente, antes de cada llamada MQPUT o MQPUT1 .Por ejemplo, una aplicación que desea reenviar los mensajes físicos que recibe, sin tener en cuenta si esos mensajes están en grupos o segmentos de mensajes lógicos, no debe especificar MQPMO_LOGICAL_ORDER, por dos razones:- Si los mensajes se recuperan y se ponen en orden, la especificación MQPMO_LOGICAL_ORDER asigna un nuevo identificador de grupo a los mensajes, lo que puede hacer que sea difícil o imposible que el emisor de los mensajes correlacione cualquier mensaje de respuesta o informe que resulte del grupo de mensajes.
- En una red compleja con múltiples rutas entre los gestores de colas de emisión y recepción, los mensajes físicos pueden llegar fuera de secuencia. Si no se especifica MQPMO_LOGICAL_ORDER ni MQGMO_LOGICAL_ORDER en la llamada MQGET, la aplicación de reenvío puede recuperar y reenviar cada mensaje físico tan pronto como llegue, sin esperar a que llegue el mensaje siguiente en orden lógico.
Las aplicaciones que generan mensajes de informe para mensajes de grupos o segmentos de mensajes lógicos también no deben especificar MQPMO_LOGICAL_ORDER al colocar el mensaje de informe.
MQPMO_LOGICAL_ORDER se puede especificar con cualquiera de las demás opciones MQPMO_*.
Colocación de grupos ordenados lógicamente en una cola de clúster (MQOO_BIND_ON_GROUP)
- La llamada MQPUT debe especificar MQPMO_LOGICAL_ORDER
- La llamada MQOPEN debe especificar una de las dos opciones siguientes:
- MQOO_BIND_ON_GROUP
- MQOO_BIND_AS_Q_DEF, y la definición de cola debe especificar DEFBIND(GROUP)
Entonces el equilibrio de la carga de trabajo se activa entre grupos de mensajes, sin necesidad de ejecutar MQCLOSE y MQOPEN para la cola. Entre grupos significa que MQMF_MSG_IN_GROUP se establece en MQMD(v2) o MQMDE, y no hay ningún grupo parcialmente completo en curso. Cuando un grupo está en curso, se reutilizan el gestor de colas resuelto y el nombre de cola en el descriptor de contexto de objeto.
Si el mensaje anterior era MQPMO_LOGICAL_ORDER y/o se ha establecido MQMF_MSG_IN_GROUP pero el mensaje actual no forma parte del grupo, la llamada PUT falla con MQRC_INCOMPLETE_GROUP.
Si una operación MQPUT individual no especifica MQPMO_LOGICAL_ORDER, y no hay ningún grupo actual activo, el equilibrado de la carga de trabajo se activa para ese mensaje (como si la llamada MQOPEN hubiera especificado MQOO_BIND_NOT_FIXED).
No se lleva a cabo ninguna reasignación para los mensajes enlazados a un destino utilizando MQOO_BIND_ON_GROUP. Para más información sobre la reasignación, véase Grupos de mensajes.