Una transacción CICS no es una petición HTTP
Una transacción CICS no es una petición HTTP. Modele estado, COMMAREA, syncpoints y commit distribuido sin alterar el comportamiento del negocio.

La modernización de CICS más peligrosa es la que parece obvia. Un equipo encuentra un código de transacción, envuelve su entrada en JSON, le asigna una ruta POST y da por entendido el límite. Las pantallas funcionan en una demostración. Con tráfico real aparecen envíos duplicados, estado obsoleto, commits prematuros y actualizaciones distribuidas a medias.
Una transacción CICS es una tarea con recursos gestionados por CICS, reglas de recuperación y un final preciso. Una petición HTTP es un intercambio de transporte en el que el servidor puede perder al cliente antes de que cualquiera sepa qué ocurrió. Ambos pueden llevar la misma orden de negocio, pero no definen la misma unidad de trabajo. Una reescritura segura conserva la máquina de estados del negocio y hace explícito el límite del commit, en vez de dejar que el framework web lo invente.
El límite de la tarea determina la semántica
Una transacción CICS empieza cuando CICS adjunta una tarea y termina cuando el programa de nivel superior devuelve el control o la tarea finaliza. Esa tarea puede invocar varios programas con LINK o transferir el control con XCTL. Esas llamadas no crean nuevas transacciones solo porque el control cruce un módulo. El ID de transacción elige un punto de entrada; no describe un método de petición, un recurso ni un contrato de respuesta.
HTTP aporta otra envoltura. Una petición tiene cabeceras, cuerpo, conexión y respuesta, pero el protocolo no sabe qué escrituras forman una acción de negocio. Un servidor puede hacer commit antes de enviar la respuesta. El cliente puede agotar su tiempo después del commit y reintentar. Un proxy puede repetir una petición que la aplicación nunca clasificó como segura. Ningún caso tiene un equivalente directo en el modelo de tareas de CICS.
La primera pregunta de diseño no es qué URL sustituirá a un ID de cuatro caracteres. Pregunte qué cambios recuperables deben tener éxito o fallar juntos, qué entrada inicia esa decisión y qué hecho duradero demuestra que terminó. Solo entonces una ruta puede representar la orden con honestidad.
La distinción también evita un error habitual de granularidad. Una interacción de pantalla puede ejecutar una tarea CICS, varios programas enlazados y cambios en Db2 y recursos CICS recuperables. Separar cada programa en un servicio de red introduce fallos dentro de una unidad que antes fallaba entera. Unir varios pasos pseudoconversacionales en una petición HTTP larga comete el error opuesto: mantiene trabajo abierto mientras una persona piensa.
Trate el grafo de llamadas heredado como prueba, no como arquitectura objetivo. Marque inicios de tarea, enlaces LINK y XCTL, cambios en archivos y bases, mensajes salientes, syncpoints explícitos y retornos del nivel superior. Los límites del trabajo recuperable rara vez coinciden con la pantalla o el programa.
La pseudoconversación libera la tarea entre pantallas
Una aplicación pseudoconversacional parece una sesión para el usuario, pero ejecuta una serie de tareas breves. Cada tarea recibe una entrada, reconstruye el contexto necesario, envía la pantalla siguiente, nombra la transacción para la próxima entrada, pasa datos de continuación y vuelve a CICS. Mientras el usuario lee, ninguna tarea de aplicación espera su respuesta.
La documentación de CICS de IBM lo describe como transacciones no conversacionales incrustadas en una secuencia. El diseño ahorra memoria y evita retener recursos exclusivos durante el tiempo de reflexión humano. La aparente conversación es una experiencia de usuario, no una transacción continua.
Una salida COBOL simplificada suele tener esta forma:
EXEC CICS SEND MAP('ACCT1') MAPSET('ACCT')
END-EXEC
EXEC CICS RETURN
TRANSID('AC02')
COMMAREA(WS-CONTINUATION)
LENGTH(WS-CONTINUATION-LEN)
END-EXEC
RETURN TRANSID no llama de inmediato a AC02 en el caso normal. Indica a CICS qué transacción recibirá la siguiente entrada del terminal. La tarea actual termina. Cuando llega esa entrada, CICS adjunta una nueva tarea y el primer programa puede acceder a la COMMAREA transferida. Un channel también puede cumplir esa función.
Mapear la secuencia a un solo objeto de sesión HTTP suele ocultar dos cosas independientes. El navegador tiene estado de presentación, como la página y los campos editables. La aplicación tiene estado del flujo, como la cuenta elegida, la versión leída, los permisos comprobados y las órdenes permitidas. La segunda categoría necesita una representación versionada en el servidor o un token resistente a manipulaciones. Un mapa de sesión en memoria no es suficientemente duradero ni claro.
El límite moderno debe exponer cada decisión del usuario como una orden breve. Un GET obtiene una proyección para mostrar. Un POST presenta una decisión contra una versión del flujo. Ninguna transacción de base queda abierta mientras espera el navegador. Eso se acerca a la intención operativa de la pseudoconversación aunque el transporte sea distinto.
Una COMMAREA es un contrato de continuación, no una sesión
Una COMMAREA es un contrato de bytes entre programas o tareas sucesivas. Su copybook da significado a esos bytes. Puede contener código de función, identificadores, indicadores, campos de pantalla, códigos de retorno y datos para la tarea siguiente. También puede guardar residuos históricos que ningún camino activo lee. Llamar estado de sesión a toda la estructura evita el análisis que exige la migración.
En una pseudoconversación, CICS conserva la COMMAREA transferida para el primer programa de la siguiente tarea. IBM documenta un límite importante: la COMMAREA no es recuperable. Si una tarea hace commit de un cambio de base y prepara bytes de continuación, esos bytes no se vuelven parte del mismo recurso recuperable porque CICS los lleve adelante.
El límite práctico de tamaño también advierte contra usarla como almacén de objetos. El máximo teórico documentado para RETURN ronda los 32 KB, con una recomendación histórica de IBM de usar menos. Channels y containers eliminan la restricción de una única COMMAREA y ofrecen compartimentos con nombre, pero no convierten la continuación en verdad duradera del negocio.
Decodifique cada COMMAREA en tres categorías. La identidad de negocio incluye valores estables como cliente, siniestro o pedido. El control del flujo incluye etapa, función, acción previa y versión optimista. El residuo de presentación incluye etiquetas copiadas, literales de pantalla, cursor y campos que pueden volver a consultarse. Guarde el estado de negocio, modele el control explícitamente y descarte la presentación salvo que afecte al comportamiento observable.
La longitud forma parte del contrato. Un programa COBOL receptor suele comprobar EIBCALEN antes de leer DFHCOMMAREA; una versión posterior del copybook puede añadir campos. Un decodificador JSON que exige cada campo nuevo puede ser menos compatible que el programa antiguo. Registre longitudes aceptadas, inicialización, convenciones de espacios y ceros, conversión EBCDIC, decimales empaquetados y ramas de redefinición antes de diseñar un sustituto tipado.
No serialice el copybook como un JSON enorme y lo llame conservación. Expondría la disposición de memoria como API pública, permitiría al cliente controlar campos indebidos y convertiría cada cambio del copybook en cambio de API. Traduzca los bytes a una orden con intención clara y conserve la entrada cruda solo en pruebas y evidencias de auditoría cuando la política lo permita.
Un syncpoint confirma una unidad de trabajo, no una respuesta
CICS confirma cambios recuperables en un syncpoint. La aplicación puede ejecutar EXEC CICS SYNCPOINT, y CICS también toma uno implícito cuando una tarea superior termina bien. Un abend suele activar el backout dinámico de cambios en recursos recuperables dentro de la unidad actual. Ese ciclo no guarda relación automática con que una respuesta HTTP llegue al llamante.
La consecuencia se pierde con facilidad en un wrapper. Suponga que la tarea actualiza Db2, escribe en una cola recuperable, vuelve bien y el gateway pierde la conexión antes de entregar la respuesta. CICS hizo commit. El llamante ve un timeout. Si el sustituto interpreta el timeout como fallo y repite sin una regla de idempotencia, ejecuta dos veces la acción.
También existe el fallo inverso. Un handler web puede escribir 200 OK en un búfer y fallar después, cuando el commit de base ocurre al volver el código. Las abstracciones hacen que construir la respuesta parezca terminar, aunque la finalización duradera no haya sucedido. El sustituto debe definir éxito como resultado de negocio confirmado y ordenar la respuesta alrededor de ese hecho.
Inventaríe cada syncpoint explícito en vez de asumir que solo existe el final. Un syncpoint cierra la unidad actual y abre otra mientras la tarea sigue. Un rollback solo revierte cambios desde el último, no todo lo que hizo la tarea. Si un programa confirma una fila de auditoría a mitad y luego revierte una cuenta, envolver todo el handler en una transacción cambia la recuperación visible.
Los efectos no recuperables necesitan trato separado. Una llamada externa, un correo entregado a un sistema no transaccional o una escritura no recuperable no se revierte con Db2. La aplicación anterior puede depender del orden, los reintentos o la reparación del operador. Conserve el resultado, no la ficción de que una transacción del lenguaje controla todos los recursos.
El commit en dos fases no se sustituye con reintentos
El commit en dos fases coordina gestores recuperables en una unidad distribuida. En la fase uno, los participantes se preparan y prometen poder cumplir la decisión. En la fase dos, el coordinador ordena confirmar o revertir. Si la comunicación falla después de preparar, un participante puede quedar en duda hasta conocer la decisión. Esa incertidumbre es un estado del protocolo, no un error común.
CICS coordina trabajo distribuido entre recursos y conversaciones válidos. La documentación de IBM indica que un proceso distribuido debe tener un iniciador del syncpoint, mientras los agentes pueden aceptar o forzar rollback. El gestor de recuperación registra estado suficiente para resincronizar al volver la conexión. Una cadena HTTP no ofrece esto por defecto.
Sustituir la unidad por servicio A llama a B y reintenta si falla crea un hueco sin dueño. Si B confirma y A pierde la respuesta, A no sabe si reintentar, compensar o informar éxito. Reintentar puede duplicar el efecto. Compensar puede revertir algo que nunca ocurrió. Devolver error puede decir que falló una acción ya terminada.
Hay dos patrones honestos. Mantenga el trabajo atómico en un límite transaccional si los datos caben bajo un gestor. Si los servicios poseen datos separados, use un flujo explícito con órdenes duraderas, consumidores idempotentes, outbox o registro atómico equivalente y compensaciones diseñadas como operaciones de negocio. El segundo abandona la atomicidad inmediata y debe mostrar pendiente, completado, rechazado y reparación.
No llame commit en dos fases al segundo. Una saga coordina commits separados y posibles compensaciones. El commit en dos fases coordina una decisión entre participantes preparados. Confundirlos lleva a prometer atomicidad mientras se implementa reparación posterior.
El fallo habitual del wrapper tiene una secuencia precisa
El análisis más útil sigue una orden por el límite y registra lo que sabe cada lado. Considere una tarea CICS de pago expuesta por POST. Comprueba la cuenta, actualiza Db2, escribe un registro recuperable para el proceso posterior y vuelve normalmente.
- El cliente envía una petición con referencia
P7319. - El gateway inicia la tarea CICS y espera.
- La tarea actualiza ambos recursos y llega al syncpoint final.
- CICS hace commit, pero se cierra la conexión antes de que la respuesta llegue.
- El cliente reintenta por el timeout y otra tarea recibe la misma orden.
Si el programa genera una referencia nueva en cada llamada, la segunda tarea no reconoce la primera. Si solo comprueba el saldo, ambos intentos pueden pasar. Si HTTP crea un token de idempotencia fuera del commit del cambio, un fallo puede dejar token y pago en desacuerdo.
La solución empieza con un ID de orden estable del cliente y una reclamación atómica. Dentro de la unidad que confirma el pago, guarde ID, huella de petición, estado y referencia del resultado. Un duplicado con la misma huella devuelve el resultado. El mismo ID con otro contenido es conflicto. Un resultado pendiente recibe una respuesta pendiente veraz, no un reintento ciego.
Una respuesta mínima puede ser:
{
"command_id": "P7319",
"workflow_version": 12,
"status": "completed",
"result_ref": "PAY-88421"
}
Este registro hace más que suprimir duplicados. Da a operaciones una respuesta duradera cuando el transporte es ambiguo. También permite igualar el resultado confirmado sin fingir que entrega TCP y commit fueron un evento.
Modele el límite como órdenes y estados
El nuevo límite debe mostrar intención, estado del flujo y dueño del commit. Empiece con una tabla de transiciones, no con controladores. Para cada orden, nombre estados previos permitidos, versión, validación, escrituras recuperables, efectos externos, estado resultante y duplicados.
Una envoltura útil es deliberadamente menor que la COMMAREA:
{
"command_id": "7f6c2b1a",
"workflow_id": "CLAIM-2048",
"expected_version": 4,
"action": "approve",
"input": {
"amount": "125.00",
"currency": "USD"
}
}
El handler carga CLAIM-2048, verifica versión 4 y transición approve, aplica reglas, escribe estado y resultado en una transacción local y devuelve el resultado guardado. Si el trabajo posterior no puede unirse, el mismo commit escribe una outbox. Un dispatcher reintenta la entrega sin repetir la transición.
Mantenga los conceptos de protocolo fuera del dominio. Los estados HTTP describen el intercambio y deben mapearse desde resultados. Una versión obsoleta puede ser 409 Conflict. Una orden terminada con la misma huella devuelve su resultado. Una orden aceptada asíncronamente puede devolver 202 Accepted con referencia de estado. Son políticas del límite, no reglas de cuenta.
El siguiente ID pseudoconversacional se convierte en una decisión de transiciones permitidas, no en una redirección disfrazada. La interfaz pregunta al flujo qué acciones hay. El servidor las impone. Un llamante no puede saltar de revisión a fin adivinando una ruta.
El diseño elimina la afinidad de terminal sin perder la secuencia. Cualquier instancia maneja la siguiente orden porque el estado duradero guarda versión y resultado. Si algún estado queda en el cliente, fírmelo, versiónelo, valide su edad y espere repeticiones. No ponga autoridad, precios ni permisos en un token sin firma.
La idempotencia necesita un contrato de recuperación
Una cabecera no vuelve segura una orden. El sistema necesita reglas de ámbito, persistencia, comparación, concurrencia, retención y recuperación. Sin ellas, la cabecera solo decora el mismo fallo ambiguo.
Limite la clave al actor y operación. Vincúlela a una huella canónica. Imponga unicidad en la transacción que posee el cambio. Devuelva el resultado solo si coincide la huella. Conserve registros según la ventana de repetición del negocio, no según una caducidad cómoda de caché.
Los duplicados concurrentes necesitan un ganador. Una restricción única o fila bloqueada reclama la ejecución. Los demás deben ver pending y consultar, o esperar con límite, no iniciar de nuevo. Si el ganador cae antes del commit, reclamación y cambios revierten juntos. Si cae después, otros encuentran el registro completo.
La recuperación también necesita estados visibles. received, completed y rejected cubren el camino limpio; dispatch_pending, compensation_pending y manual_review describen trabajo tras un límite no transaccional. No los convierta todos en HTTP 500. El operador necesita IDs, última transición duradera, efecto intentado y siguiente acción segura.
Los reintentos pertenecen a la capa que sabe si se puede repetir. Una biblioteca puede reintentar conexión o lectura. No debe repetir en silencio un POST sin contrato. Dentro, un dispatcher reintenta porque el consumidor deduplica por ID y el productor ya confirmó la intención.
Es más estricto que muchos wrappers CICS, pero expresa la protección que CICS daba mediante recuperación y syncpoints coordinados. Al cruzar HTTP y bases independientes, la aplicación debe poseer la incertidumbre.
El adaptador debe declarar quién controla el commit
Un adaptador HTTP puede estar fuera de CICS, dentro de una región o tras gateway y Distributed Program Link. La ubicación cambia latencia y operación, pero importa más el dueño del commit. Quien devuelve éxito debe saber que la unidad confirmó y no debe insinuar que una llamada remota participa en su transacción local sin un coordinador real.
Un adaptador externo fino trata la transacción como procesador con resultado de transporte ambiguo. Envía ID estable, espera y puede consultar tras timeout. No abre una transacción local, llama a CICS, actualiza su tabla y supone una acción conjunta. Sin coordinación son dos commits y un hueco.
Con DPL hace falta igual cuidado. El servidor enlazado no siempre posee el syncpoint. IBM documenta que sin SYNCONRETURN no puede emitir uno independiente; el cliente posee la unidad distribuida. Con SYNCONRETURN, el servidor puede confirmar al volver, pero separa sus cambios del trabajo anterior del llamante. Es diseño transaccional, no ajuste de rendimiento.
Antes de ubicarlo, responda cuatro preguntas:
- ¿Qué proceso asigna el ID estable?
- ¿Qué recurso guarda el resultado autoritativo?
- ¿Qué coordinador cubre a todos los participantes?
- ¿Cómo resuelve el llamante un timeout sin repetir el efecto?
Si hay dos bases y ningún coordinador, diseñe un límite asíncrono. Confirme orden y outbox juntas al inicio. Deje que CICS reclame el ID y guarde resultado con la actualización. Concilie acuses sin confundir entrega con commit. Añade estados que describen incertidumbre ya existente.
HTTP síncrono aún puede estar delante. El adaptador espera brevemente completed o rejected y devuelve 202 Accepted si continúa. Una lectura muestra el resultado duradero. El usuario ve rapidez normal y pendiente veraz con retrasos. No mantenga abierta la conexión para imitar una tarea conversacional.
La seguridad sigue el mismo modelo. Autentique en el borde, pero pase un principal limitado y contexto autorizado. No confíe en cuenta, operador o permiso porque antes estaban en una COMMAREA protegida. Los valores que cruzan navegador o broker se validan donde se aplica la transición.
Guarde código CICS y diagnóstico en la evidencia del adaptador, y mapéelos a un contrato público pequeño. Exponer cada EIBRESP acopla clientes; tirarlos dificulta paridad y reparación. El límite necesita resultado estable para llamantes y detalle heredado para demostrar equivalencia.
Las pruebas de paridad deben romper conversaciones
Comparar campos felices no demuestra la migración. El arnés debe comparar comportamiento confirmado entre límites, reintentos, abends, continuación obsoleta y fallos cerca del syncpoint. Una pantalla igual puede ocultar otra unidad de trabajo.
Cree trazas de tráfico grabado solo bajo las reglas de datos de la organización. Capture estado inicial, bytes y campos, transacción, cambios, ubicaciones de syncpoint, salidas, siguiente transacción y estado final. El enmascarado debe conservar diferencias que cambian ramas, como espacios frente a valores bajos o códigos con la misma etiqueta.
Ejecute ambas rutas con datos aislados y reiniciables. Compare resultados, no ruido. Tiempos, IDs y orden pueden normalizarse; importes, estados, permisos y efectos confirmados deben coincidir.
La matriz debe incluir:
- Repetir la orden antes y después de terminar.
- Perder la respuesta tras commit y repetir con el mismo ID.
- Fallar antes del syncpoint y tras un efecto no recuperable.
- Enviar una orden válida con versión obsoleta.
- Reanudar con cada longitud y versión de COMMAREA.
CodeHero usa un arnés de paridad contra tráfico de producción grabado al reescribir CICS y código contiguo, porque la similitud del código no revela diferencias de recuperación. El mismo arnés debe inyectar fallos antes de confiar escrituras al sustituto.
Conserve el comportamiento sin conservar el accidente
Modelar bien no exige recrear CICS en un servicio web. Exige conservar reglas observables: órdenes permitidas, cambios que confirman juntos, resultado de duplicados, trabajo sin terminar y recuperación conocida.
Algunos detalles deben retirarse. Un ID de cuatro caracteres no necesita ser ruta. Una COMMAREA no necesita ser payload público. La afinidad de terminal no necesita ser sesión pegajosa. Un límite de gestor debe sobrevivir hasta sustituir su atomicidad deliberadamente por flujo y reparación.
Escriba una especificación por orden: identidad estable, estado previo, versión, dueño, efectos dentro y fuera, duplicado y reparación del operador. Revísela con quienes diagnostican CICS. Suelen encontrar un syncpoint implícito, una cola o un supuesto de reinicio ausente.
La prueba difícil es perder la respuesta tras commit. Si el diseño explica qué repite el cliente, qué lee el servidor, qué devuelve y por qué no repite el efecto, el límite probablemente es real. Si depende de que petición y transacción terminen juntas, aún confunde HTTP con CICS.
Preguntas frecuentes
¿Una transacción CICS es lo mismo que una transacción de base de datos?
No. Una transacción CICS es una tarea elegida por un ID, mientras la transacción de base es un participante de su unidad de trabajo. CICS puede coordinar Db2 y otros recursos recuperables en un syncpoint.
¿Puede una transacción CICS convertirse en un endpoint REST?
A veces, pero los nombres no demuestran límites iguales. Asigne un endpoint a una orden solo tras identificar transición, escrituras recuperables, syncpoints, duplicados y resultado.
¿Qué ocurre con una COMMAREA entre tareas pseudoconversacionales?
CICS conserva los bytes y los ofrece al primer programa de la tarea siguiente asociada al terminal. Lleva continuación, pero no es un registro recuperable.
¿Debe la aplicación migrada guardar la COMMAREA en una sesión HTTP?
No por norma. Guarde negocio y flujo en un registro versionado, recalcule presentación y use estado firmado del cliente solo para valores que pueda conservar y repetir con seguridad.
¿Cuándo hace commit CICS?
En un syncpoint explícito o al final normal de una tarea superior. Un abend suele revertir cambios recuperables no confirmados de la unidad actual.
¿Una respuesta HTTP 200 significa que CICS confirmó el trabajo?
Solo si el adaptador la construye desde un resultado confirmado conocido. La conexión puede fallar después del commit, y el framework preparar respuesta antes del commit real.
¿Pueden los reintentos sustituir el commit en dos fases?
No. Repiten intentos, no coordinan una decisión entre gestores preparados. Use una transacción local o diseñe estados duraderos, idempotencia, outbox y compensaciones.
¿Cómo se tratan peticiones HTTP duplicadas?
Dé a cada orden un ID estable y guárdelo con huella y resultado en la misma transacción del cambio. Devuelva el resultado exacto y rechace el ID con otro contenido.
¿Son duraderos los channels y containers CICS?
No. Mejoran el paso estructurado y evitan el tamaño de una COMMAREA, pero no sustituyen un flujo duradero ni cambian el commit del negocio.
¿Qué compara una prueba de paridad CICS?
Estado inicial y final, transiciones, salidas, efectos y duplicados. Inyecte timeouts, abends, versiones obsoletas y respuestas perdidas alrededor de syncpoints.