Pyxis Logo
Inicio / Formación IBM / Artículo técnico

Un segundo análisis del parámetro JCL GDGBIAS

Un artículo práctico que muestra cómo GDGBIAS=JOB y GDGBIAS=STEP alteran la resolución relativa de GDGs entre job steps.

16 min read
Publicado 2026-05-25
Pyxis editorial team
Califique este artículo
Calificación media: Sin calificación
Su calificación: Sin calificación
visualizaciones: 0
Ilustración abstracta de estilo mainframe que muestra grupos de datos generacionales secuenciales cambiando entre steps de jobs en z/OS

GDGBIAS es un parámetro de JCL que puede pasar desapercibido a primera vista, pero que puede cambiar el significado y el comportamiento de todo un job.

Si un job crea y más tarde reutiliza un data set referido como MY.GDG(+1), podemos plantear la siguiente cuestión:

  • ¿Los steps posteriores deben seguir usando el mismo mapeo relativo-a-absoluto establecido anteriormente en el job?
  • ¿O z/OS debe recalcular los mapeos, por ejemplo de (0) y (+1), en cada nuevo job step?

Este artículo analiza el efecto de GDGBIAS y muestra JCL que puede enviar para observar cómo GDGBIAS=JOB y GDGBIAS=STEP se comportan de forma diferente.

1. Objetivos del laboratorio

Al final del artículo debería poder:

  • Explicar la diferencia entre GDGBIAS=JOB y GDGBIAS=STEP
  • Predecir cómo se resuelven (0) y (+1) después de que un step anterior catalogue una nueva generación
  • Construir un pequeño GDG de prueba y reproducir la diferencia en batch
  • Reconocer por qué VOL=REF, los passed data sets y los cambios de catálogo realizados por utilidades hacen más importante esta elección

2. Entorno necesario

Para la parte práctica, use:

  • z/OS 2.1 o posterior
  • JES2 o JES3

3. Introducción

z/OS mantiene un mapeo interno entre una referencia relativa a un GDG y el nombre absoluto de la generación que realmente se asignará.

Si asumimos que el catálogo contiene actualmente la generación corriente

&SYSUID..GDGTEST.BASE.G0010V00

entonces los nombres relativos se resuelven de la siguiente forma:

  • (0) se asigna a G0010V00 (a menos que exista una versión Vnn con nn > 00)
  • (+1) se asigna a la generación siguiente, por ejemplo G0011V00

La cuestión es: ¿qué ocurre después de que un step del mismo job catalogue la generación G0011V00? Ahí es donde el valor de GDGBIAS pasa a importar. GDGBIAS acepta dos valores (JOB y STEP) que producen comportamientos distintos:

AtributoGDGBIAS=JOBGDGBIAS=STEP
Punto de resoluciónPrimera referencia al GDG en el jobInicio de cada step
Persistencia del mapeoSe conserva en los steps siguientesSe reconstruye en cada frontera entre steps
Significado de (0) en el Step 2 después de que el Step 1 cree (+1)Sigue siendo la generación que era corriente antes del Step 1Pasa a ser la generación recién creada en el Step 1
Significado de (+1) en el Step 2 después de que el Step 1 cree (+1)Sigue siendo la generación creada anteriormente en el jobPasa a ser una nueva generación aún no creada

Esto significa que GDGBIAS=JOB mantiene consistencia entre steps dentro del mismo job, mientras que GDGBIAS=STEP fuerza una nueva evaluación contra el estado actual del catálogo en cada step.

4. Preparación práctica: definir un GDG desechable para pruebas

Antes de comparar los dos modos de GDGBIAS, cree una pequeña base GDG y una generación inicial. Copie y envíe el JCL siguiente (puede ser necesario ajustar la JOB card a los requisitos de su instalación):

//GDGPREP  JOB ,'GDG PREP',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//DELETE   EXEC PGM=IDCAMS
//SYSPRINT DD   SYSOUT=*
//SYSIN    DD   *
  DELETE &SYSUID..GDGTEST.BASE GDG FORCE
  IF LASTCC LE 8 THEN SET MAXCC = 0
/*
//DEFINE   EXEC PGM=IDCAMS
//SYSPRINT DD   SYSOUT=*
//SYSIN    DD   *
  DEFINE GDG (NAME(&SYSUID..GDGTEST.BASE) LIMIT(5) NOEMPTY SCRATCH)
/*
//SEED     EXEC PGM=IEFBR14
//G0001    DD   DSN=&SYSUID..GDGTEST.BASE(+1),
//              DISP=(NEW,CATLG,DELETE),
//              SPACE=(TRK,(1,1)),
//              DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
//              UNIT=SYSDA

Verifique con ISPF 3.4 o LISTCAT. En este punto debería tener exactamente una generación corriente bajo la base:

//GDGLIST  JOB ,'GDG LIST',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//LISTCAT  EXEC PGM=IDCAMS
//SYSPRINT DD   SYSOUT=*
//SYSIN    DD   *
  LISTCAT ENTRIES(&SYSUID..GDGTEST.BASE) ALL
/*

6. Comportamiento de GDGBIAS=JOB

Envíe un job con dos steps que:

1. Cree una nueva generación (+1) 2. En el step siguiente, intente leer (+1) como data set catalogado

//GDGJOB   JOB ,'GDG JOB BIAS',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID,
//             GDGBIAS=JOB
//STEP1    EXEC PGM=IEFBR14
//NEWGEN   DD   DSN=&SYSUID..GDGTEST.BASE(+1),
//              DISP=(NEW,CATLG,DELETE),
//              SPACE=(TRK,(1,1)),
//              DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
//              UNIT=SYSDA
//STEP2    EXEC PGM=IEBGENER
//SYSPRINT DD   SYSOUT=*
//SYSUT1   DD   DSN=&SYSUID..GDGTEST.BASE(+1),DISP=SHR
//SYSUT2   DD   SYSOUT=*
//SYSIN    DD   DUMMY

El resultado esperado es que STEP1 catalogue una nueva generación y que STEP2 termine correctamente porque:

  • En GDGBIAS=JOB, el mapeo relativo construido anteriormente en el job se mantiene vigente
  • El (+1) en STEP2 sigue mapeando a la generación absoluta creada en STEP1

Este es el comportamiento clásico en el que los mapeos se establecen para el job y se mantienen a partir de ahí.

7. Comportamiento de GDGBIAS=STEP

Envíe ahora el mismo JCL pero con GDGBIAS a nivel de step:

//GDGSTEP  JOB ,'GDG STEP BIAS',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID,
//             GDGBIAS=STEP
//STEP1    EXEC PGM=IEFBR14
//NEWGEN   DD   DSN=&SYSUID..GDGTEST.BASE(+1),
//              DISP=(NEW,CATLG,DELETE),
//              SPACE=(TRK,(1,1)),
//              DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
//              UNIT=SYSDA
//STEP2    EXEC PGM=IEBGENER
//SYSPRINT DD   SYSOUT=*
//SYSUT1   DD   DSN=&SYSUID..GDGTEST.BASE(+1),DISP=SHR
//SYSUT2   DD   SYSOUT=*
//SYSIN    DD   DUMMY

Esta vez, STEP1 termina correctamente y cataloga una nueva generación, pero STEP2 fallará la asignación. ¿Por qué?

  • Como GDGBIAS=STEP, z/OS limpia el mapeo anterior al pasar de un step a otro
  • Cuando STEP2 empieza, la generación creada en STEP1 ya se ha convertido en el nuevo (0)
  • (+1) pasa a significar la siguiente generación aún no creada
  • DISP=SHR sobre una generación que todavía no existe provoca el fallo

8. Vamos a demostrar que (0) también cambia con GDGBIAS=STEP

Los dos jobs anteriores muestran el efecto sobre (+1). El siguiente par muestra el efecto sobre (0). Empiece creando la nueva generación:

//GDGMAKE  JOB ,'GDG MAKE',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//STEP1    EXEC PGM=IEFBR14
//NEWGEN   DD   DSN=&SYSUID..GDGTEST.BASE(+1),
//              DISP=(NEW,CATLG,DELETE),
//              SPACE=(TRK,(1,1)),
//              DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
//              UNIT=SYSDA

Después compare estos dos jobs que efectuarán la lectura.

JCL con GDGBIAS=JOB:

//READJOB  JOB ,'READ JOB',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID,
//             GDGBIAS=JOB
//STEP1    EXEC PGM=IEBGENER
//SYSPRINT DD   SYSOUT=*
//SYSUT1   DD   DSN=&SYSUID..GDGTEST.BASE(0),DISP=SHR
//SYSUT2   DD   SYSOUT=*
//SYSIN    DD   DUMMY

JCL con GDGBIAS=STEP en un flujo con varios steps:

//READSTEP JOB ,'READ STEP',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID,
//             GDGBIAS=STEP
//STEP1    EXEC PGM=IEFBR14
//NEWGEN   DD   DSN=&SYSUID..GDGTEST.BASE(+1),
//              DISP=(NEW,CATLG,DELETE),
//              SPACE=(TRK,(1,1)),
//              DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
//              UNIT=SYSDA
//STEP2    EXEC PGM=IEBGENER
//SYSPRINT DD   SYSOUT=*
//SYSUT1   DD   DSN=&SYSUID..GDGTEST.BASE(0),DISP=SHR
//SYSUT2   DD   SYSOUT=*
//SYSIN    DD   DUMMY

Qué debe observar:

  • En JOB, (0) en un step posterior sigue significando la generación que era corriente antes de la primera resolución de la base en el job
  • En STEP, (0) en el step posterior pasa a significar la generación creada por STEP1

Esta distinción importa siempre que un job espere que “corriente” signifique “corriente cuando empezó el job” en lugar de “corriente ahora”.

9. Caso avanzado 1: la paradoja de VOL=REF

La cláusula VOL=REF puede sorprender, porque no se comporta como una referencia GDG DSN normal. El riesgo práctico es este:

  • Con GDGBIAS=JOB, una referencia DSN=base(+1) puede seguir refiriéndose a la misma generación absoluta creada antes en el job
  • Pero una referencia VOL=REF puede seguir resolviéndose a partir del estado del catálogo al principio del step, en lugar del mapeo GDG a nivel de job que usted esperaba

Considere el siguiente job:

//GDGVREF  JOB ,'VOL REF',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID,
//             GDGBIAS=JOB
//STEP1    EXEC PGM=IEFBR14
//OUT1     DD   DSN=&SYSUID..GDGTEST.BASE(+1),
//              DISP=(NEW,CATLG,DELETE),
//              SPACE=(TRK,(1,1)),
//              DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
//              UNIT=SYSDA
//STEP2    EXEC PGM=IEFBR14
//IN1      DD   DSN=&SYSUID..GDGTEST.BASE(+1),DISP=SHR
//VOLX     DD   DSN=&SYSUID..GDGTEST.WORK,
//              DISP=(NEW,CATLG,DELETE),
//              UNIT=SYSDA,
//              SPACE=(TRK,(1,1)),
//              VOL=REF=*.IN1

Mucha gente asume que IN1 está reabriendo la generación creada en STEP1 y que cualquier herencia de volumen basada en esa intención lógica debería mantenerse alineada.

Sin embargo, esa suposición no está garantizada cuando hay GDGs implicados. La regla práctica más segura es:

  • Si necesita heredar el volumen de un data set creado anteriormente en el mismo job, prefiera una referencia concreta como VOL=REF=*.stepname.ddname
  • No suponga que VOL=REF=MY.GDG(+1) se comportará como la referencia de DSN estable entre steps que tenía en mente

10. Caso avanzado 2: contaminación por concurrencia entre jobs

Una diferencia arquitectónica importante entre GDGBIAS JOB y GDGBIAS STEP aparece cuando otro workload actualiza la misma base GDG mientras su job todavía está en ejecución.

Con GDGBIAS=JOB:

  • Su job trabaja efectivamente con un mapeo interno “congelado” en cuanto la base se resuelve por primera vez
  • Las actualizaciones externas posteriores del catálogo no impactan las referencias relativas ya establecidas

Con GDGBIAS=STEP:

  • Cada transición entre steps inicia una nueva consulta al catálogo
  • Si otro job cataloga una nueva generación entre su STEP1 y su STEP2, su STEP2 puede heredar esa nueva baseline

Esto significa que GDGBIAS=STEP no es solo “más actual”. Su job también queda expuesto a actividad externa concurrente que modifique el catálogo.

Consecuencia práctica:

  • Si su JCL asume que las referencias (+1) deben ser estables y resolver al mismo data set, use GDGBIAS=JOB
  • Si su JCL pretende reflejar el estado actual del catálogo en cada step, STEP será la opción correcta

11. Caso avanzado 3: pérdida de sincronización con el catálogo provocada por utilidades

Si un step usa una utilidad como IDCAMS para manipular directamente entradas de GDG, puede cambiar el catálogo de una forma que no equivale a la secuencia normal de asignación JCL.

Por ejemplo:

//FIXCAT   EXEC PGM=IDCAMS
//SYSPRINT DD   SYSOUT=*
//SYSIN    DD   *
  DELETE &SYSUID..GDGTEST.BASE(0)
/*

¿Por qué importa esto?

  • Con GDGBIAS=JOB, los steps JCL posteriores pueden seguir trabajando a partir del mapeo interno anterior, aunque el catálogo haya sido cambiado entretanto, lo que puede originar errores
  • Con GDGBIAS=STEP, la transición al step siguiente fuerza una nueva búsqueda y refleja de forma natural el estado actual del catálogo

Este es uno de los pocos casos en los que GDGBIAS=STEP puede parecer “autocorrectivo”, mientras que JOB puede volverse inadecuado. La misma persistencia que protege un job de interferencia externa también puede conservar un mapeo que ya no coincide con el catálogo real después de cambios realizados por utilidades.

12. Passed data sets: patrones seguros e inseguros

Cuando la generación creada se pasa al step siguiente en lugar de reabrirse desde el catálogo, el patrón más seguro es usar VOL=REF en lugar de usar el nombre relativo del GDG.

//PASSJOB  JOB ,'PASS GDG',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID,
//    GDGBIAS=STEP
//STEP1    EXEC PGM=IEBGENER
//SYSPRINT DD   SYSOUT=*
//SYSUT1   DD   *
STEP1 WRITES THIS RECORD
/*
//SYSUT2   DD   DSN=&SYSUID..GDGTEST.BASE(+1),
//              DISP=(NEW,PASS,DELETE),
//              SPACE=(TRK,(1,1)),
//              DCB=(RECFM=FB,LRECL=80,BLKSIZE=0),
//              UNIT=SYSDA
//SYSIN    DD   DUMMY
//STEP2    EXEC PGM=IEBGENER
//SYSPRINT DD   SYSOUT=*
//SYSUT1   DD   DSN=*.STEP1.SYSUT2,DISP=OLD
//SYSUT2   DD   SYSOUT=*
//SYSIN    DD   DUMMY

¿Por qué es más seguro?

  • El step receptor usa directamente el passed data set
  • No depende de recalcular la numeración relativa del GDG después de una frontera entre steps

Alternativa menos segura bajo GDGBIAS=STEP:

//SYSUT1   DD   DSN=&SYSUID..GDGTEST.BASE(+1),DISP=SHR

Si la generación fue catalogada antes del inicio del step receptor, ese (+1) ya no apuntará al archivo pretendido.

La regla práctica es simple:

  • Si está pasando una generación GDG entre steps, prefiera *.step.dd en lugar de volver a derivar el destino a partir de una referencia GDG relativa

13. Concatenaciones GDG ALL

Referenciar el nombre base del GDG sin una generación relativa explícita produce una asignación GDG ALL.

Ejemplo:

//READALL  EXEC PGM=IEBGENER
//SYSPRINT DD   SYSOUT=*
//SYSUT1   DD   DSN=&SYSUID..GDGTEST.BASE,DISP=SHR
//SYSUT2   DD   SYSOUT=*
//SYSIN    DD   DUMMY

Esto indica a z/OS que construya una concatenación de generaciones activas de la base.

Por qué GDGBIAS importa aquí:

  • Con GDGBIAS=JOB, la lista lógica detrás de esa concatenación queda ligada a la visión GDG establecida anteriormente en el job
  • En GDGBIAS=STEP, la concatenación se reconstruye a partir de la visión actual del catálogo al inicio del step

Así, si un step anterior cataloga una nueva generación:

  • GDGBIAS=JOB tiende a mantener estable la visión anterior de la concatenación
  • GDGBIAS=STEP tiende a incluir automáticamente la generación más reciente en la visión GDG ALL del step siguiente

Esto importa en jobs de reporting o replay donde un nombre base sin generación explícita se usa como atajo para “todas las generaciones corrientes”.

14. Restarts diferidos de step

El comportamiento en restart es otro punto importante que conviene tener en cuenta.

Con GDGBIAS=JOB:

  • La ejecución reiniciada reconstruye su visión en memoria a partir del estado del catálogo existente en el momento del restart
  • Si steps anteriores de la ejecución inicial ya habían catalogado nuevas generaciones, esa baseline en el momento del restart puede diferir de la baseline asumida por el flujo original no reiniciado

Con GDGBIAS=STEP:

  • La entrada directa a un step ya parte de un modelo de recálculo de referencias
  • El comportamiento en restart queda por ello naturalmente más alineado con el diseño de este modo

Esto no significa que STEP sea siempre mejor para restart. Significa que STEP suele ser más intuitivo cuando se espera que el restart siga el estado actual del catálogo sin exigir cálculos manuales de offset.

15. Cómo elegir

Si tuviéramos que reducir la decisión a una frase:

  • Elija JOB cuando el job necesite una instantánea interna estable
  • Elija STEP cuando el job deba volver a enlazarse con el catálogo activo en cada frontera entre steps

Use GDGBIAS=JOB cuando:

  • El job deba operar sobre una instantánea estable de la numeración relativa del GDG dentro del propio job
  • Los steps posteriores deban seguir refiriéndose exactamente a las mismas generaciones absolutas elegidas antes en el flujo
  • Las actualizaciones externas concurrentes del catálogo no deban cambiar el significado de las referencias relativas a mitad de la ejecución

Use GDGBIAS=STEP cuando:

  • Cada step deba reflejar el estado actual del catálogo
  • Un procesamiento orientado a utilidades o restart se beneficie de una reevaluación en cada frontera entre steps
  • Esté preparado para que (0) y (+1) cambien después de actividad intermedia en el catálogo

16. Codificación y alcance

GDGBIAS puede controlarse a varios niveles:

  • Valor por omisión de JES o de la job class (JOBCLASS(n) GDGBIAS=...)
  • Override explícito en la sentencia JOB
//DAILYJOB JOB (ACCT),'DATA PROCESSING',CLASS=A,GDGBIAS=STEP

El operador puede cambiar dinámicamente la configuración de la job class en JES:

$T JOBCLASS(A),GDGBIAS=STEP

Si omite el parámetro, se aplicará el valor por omisión del sistema o de la job class.

17. Qué conviene retener

La regla práctica más importante es simple:

  • GDGBIAS=JOB congela el significado relativo del GDG dentro del job
  • GDGBIAS=STEP recalcula el significado relativo del GDG en cada transición entre steps

Por eso GDGBIAS debe formar parte del diseño arquitectónico de un flujo de job batch, y no ser una decisión de última hora al codificar la job card.

18. Documentación útil de IBM

Estas referencias son útiles para obtener información adicional:

Más en esta área

Más en esta área

Volver a formación
Categoría de artículos

Artículos de z/OS

Consulta todos los artículos técnicos de z/OS en una sola página de categoría.

Abrir categoría z/OS