Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
dairolozano
Contributor


En muchas de las aplicaciones estándar de SAP, los cambios no se almacenan directamente en la base de datos (actualización síncrona) sino que los cambios se almacenan en buffers que son almacenados después (actualización asíncrona). 

La mayoría de las veces esto es transparente y no se genera ningún problema, por lo que no se percibe la diferencia.  De hecho, el almacenamiento asíncrono mejora el performance de los procesos debido a que los pasos siguientes a la actualización no se ven afectados por el rendimiento del motor de la base de datos.  Sin embargo, en algunas ocasiones lo que se requiere precisamente es que el proceso no continúe hasta no se hayan almacenado todos los cambios en la base de datos.  Este requerimiento es bastante común al trabajar con BAPIS, RFCs, interfaces, entre otros casos.

Lo más común es tratar de lidiar con estos problemas con una solución bastante simple: agregar una sentencia que “demore” la ejecución mientras se da tiempo a que se actualice la base de datos.  Una forma de hacerlo es mediante la sentencia WAIT.  La mecánica es más o menos de la siguiente forma:

Paso 1: Generar los cambios que finalmente llegaran a la base de datos:

CALL FUNCTION 'BAPI_OUTB_DELIVERY_CHANGE'

        EXPORTING

       header_data    = ls_header_data

       header_control = ls_header_control

       delivery       = lv_bapi_delivery

     TABLES return    = lt_return.

Paso 2: Demorar la ejecución un tiempo “prudente” mientras se realiza el almacenamiento.

WAIT UP TO 15 SECONDS.

Paso 3: Los demás pasos que se deben ejecutar solo después de realizar las actualizaciones.

Si bien podemos decir que esta solución funciona, existen varias razones para no utilizarla.  El primer problema es que es muy difícil calcular el tiempo “prudente” que se debe retrasar la ejecución.  Es fácil encontrarse con esperas que se van volviendo cada vez más largas y que sin embargo no logran ser suficientes.   Esto tiene como consecuencia un deterioro progresivo del rendimiento general del proceso.  Si a esto le sumamos que el proceso se encuentre dentro de un ciclo, estaríamos multiplicando la espera por la cantidad de iteraciones llegando a esperas de muchos minutos que pueden volverlo inutilizable o en el peor de los casos generar caídas y DUMPS por tiempo de ejecución excedido. Si lo analizamos con mas detenimiento nos daremos cuenta de que realmente esta "solución" lo que hace es lidiar con la consecuencia en lugar de resolver el verdadero problema por lo cual no es recomendable.

Afortunadamente existe una forma mucho más adecuada de resolver esta situación y es forzando la actualización de forma sincrónica usando la sentencia SET UPDATE TASK LOCAL.  De esta manera SAP Netweaver ejecuta la actualización a la base de datos en el mismo proceso en lugar de hacerlo en un proceso separado ejecutado en fondo.  Posteriormente se utiliza la sentencia COMMIT WORK para forzar la ejecución completa de todos los procesos de actualización en el proceso actual antes de continuar.

El proceso se realizaría entonces de la siguiente manera:

Paso 1: Forzar la actualización en el proceso actual:

SET UPDATE TASK LOCAL.

Paso 2: Generar los cambios que finalmente llegaran a la base de datos:

CALL FUNCTION 'BAPI_OUTB_DELIVERY_CHANGE'

        EXPORTING

       header_data    = ls_header_data

       header_control = ls_header_control

       delivery       = lv_bapi_delivery

     TABLES return    = lt_return.

Paso 3: Forzar la actualización de la base de datos.

COMMIT WORK AND WAIT.

Paso 4: Los demás pasos que se deben ejecutar solo después de realizar las actualizaciones.


En la mayoría de las situaciones esta solución es suficiente para que todas las actualizaciones se realicen antes de continuar con el paso 4.  No obstante, existe otra forma de abordar este problema que mediante el uso de sesiones que explicaremos en un próximo documento.

Como resolver problemas de actualización asíncrona en ABAP – Parte 2

1 Comment