lunes, 16 de septiembre de 2013

Wait en JCL

Este artículo surge de un problema que se nos presentó en el trabajo cuando montábamos un proceso batch de mantenimiento de tablas:

Cuando dentro de un job ejecutamos un programa que modifica la base de datos, el commit que guarda los cambios se realiza al finalizar el job.
Si un paso posterior diese error, los cambios no se quedaría grabados (haría un rollback).

Existe también la opción de realizar commit dentro del programa. Esto es habitual en los procesos rearrancables, que hacen commit cada n registros tratados (que es nuestro caso).

Incluso así, puede que los cambios no se guarden inmediatamente. En mi caso, el problema venía porque se trabaja contra vistas de las tablas, y tarda X minutos hasta que se carga sobre la tabla en sí.

¿Qué ocurre si quiero hacerme una descarga de la tabla justo después de haberla modificado? Que la descarga no contiene los cambios.

Para solventar este problemilla hemos añadido un paso de espera, que mantiene el job "esperando" el tiempo que le indiquemos. Así damos margen al DB2 para que actualice nuestra tabla.
En nuestro caso existía ya un programa para hacer el wait (desconozco su contenido), pero hemos montado el ejemplo para uso general en cualquier instalación.

El paso de "wait" consiste en ejecutar un programa REXX que recorre un bucle hasta que transcurre el tiempo que le indiquemos por parámetro (en segundos).

Código REXX:
/* rexx */                      
parse upper arg tiempowait          
   etime = time(R)              
   do while etime < tiempowait      
      nop                        
      etime = time(E)            
   end                          
exit

Y aquí va un ejemplo de job
Código JCL:
//*****************************************************************
//* PASO QUE EJECUTA UN PROGRAMA QUE MODIFICA BBDD                *
//*****************************************************************
//PASO01 EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSIN DD *
  DSN SYSTEM(DSN1)
  RUN PROGRAM(PRUEBA5) PLAN(PRUEBA5)
//SYSOUT  DD SYSOUT=*
//SYSIN   DD *
/*
//*****************************************************************
//* RETARDAMOS LA EJECUCION 3 MINUTOS PARA QUE SE CONSOLIDEN LOS  *
//* CAMBIOS EN BBDD                                               *
//*****************************************************************
//REXWAIT EXEC PGM=IKJEFT01             
//*-------                              
//SYSPROC DD DISP=SHR,DSN=LIBRERIA.CONTU.REXX 
//SYSLIST DD SYSOUT=*                   
//SYSOUT DD SYSOUT=*                    
//SYSTSPRT DD SYSOUT=*                  
//SYSTSIN DD *                          
 PGMWAIT 180                               
/*                                      
//*
//*****************************************************************
//* PASO QUE REALIZA LA DESCARGA DE LA BBDD                       *
//*****************************************************************
//UNLOAD EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
  DSN SYSTEM(DSN1)
  RUN PROGRAM(DSNTIAUL) PLAN(DSNTIAUL)
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSPUNCH DD SYSOUT=*
//SYSREC00 DD DSN=XXXX.UNLOAD.TBPRU00,
//            DISP=(NEW,CATLG,DELETE),UNIT=SYSDA,
//            SPACE=(CYL,(100,50),RLSE)
//SYSIN    DD *
   SELECT * FROM DSN1.TBPRU00
//

Ojo con poner el parámetro TIME en la cabecera del job!!! Hay que darle tiempo :P
Esperamos que os sirva de ayuda.

En este caso han sido los compañeros de MVSFORUMS los que nos han dado la idea. Muchas gracias!

4 comentarios:

bto dijo...

Gran ejemplo de Wait.
Gracias por compartir!

Tallian dijo...

Gracias bto! : )

sølrαc dijo...

Otra posibilidad es utilizar el utilidad QUIESCE (es.wikipedia.org/wiki/Modo_inactivo). Esta obliga al DB2 a escribir todos los cambios que estén en memoria al disco.

Anónimo dijo...

Wow!! De gran ayuda!! una funcionalidad que no sabia que existia pero que desde ahora este en mi base de datos... :) gracias por el aporte!!