¿Qué son los Triggers de Base de Datos (beforeSave y afterSave)?

Actualizado: septiembre de 2026

Un trigger de base de datos es un hook de código que se ejecuta solo en eventos de datos: antes del save para validar, después del save para reaccionar. La idea tiene dos linajes que comparten un principio: el trigger SQL clásico, código procedural que vive dentro del motor de la base de datos, y el hook a nivel de aplicación moderno — beforeSave, afterSave, beforeDelete — JavaScript registrado por clase en el backend. Ambos codifican la misma promesa: la regla se dispara para toda escritura, sin importar qué cliente, SDK o script la ejecutó — que es exactamente lo que la validación del lado del cliente nunca puede prometer.

Puntos clave

PreguntaRespuesta
El principioCódigo atado a eventos de datos — automático, por tabla/clase, todo camino de escritura
Before =Validar · normalizar · aplicar defaults — todavía puede cambiar o abortar la escritura
After =Reaccionar — contar, notificar, sincronizar; la escritura ya ocurrió, así que sé idempotente
Las dos formasTriggers SQL dentro del motor · hooks JS en el proceso del backend
Los bugs clásicosLógica oculta · loops infinitos de autodisparo · triggers lentos frenando cada save

El modelo de hooks en acción

Una regla de validación y su aplicación, vistas desde ambos extremos — el servidor la define una vez, y todos los clientes en todas partes la heredan:

// JavaScript — Cloud Code (cloud/main.js)
// beforeSave: validate + normalize — can still change or ABORT the write
Parse.Cloud.beforeSave('Review', (req) => {
  const stars = req.object.get('stars');
  if (stars < 1 || stars > 5) throw 'Stars must be between 1 and 5';
  const comment = req.object.get('comment');
  if (comment && comment.length > 500) {
    req.object.set('comment', comment.slice(0, 497) + '…');
  }
});

// afterSave: side effects — the write already happened; be idempotent
Parse.Cloud.afterSave('Review', async (req) => {
  if (req.object.existed()) return; // count only NEW reviews, once
  await updateAverageStars(req.object.get('movie'));
});

La familia completa de hooks extiende la misma forma a todo el ciclo de vida de los datos: beforeSave/afterSave, beforeDelete (bloquear la eliminación de un Album que todavía tiene Photos) y afterDelete (limpiar sus hijos), más beforeFind/afterFind para reescribir consultas y quitar campos de los resultados — el CRUD, envuelto.

La forma clásica: triggers SQL

CREATE TRIGGER audit_price_change
AFTER UPDATE ON products
FOR EACH ROW                              -- nivel de fila: se dispara por fila afectada
WHEN (OLD.price IS DISTINCT FROM NEW.price)
EXECUTE FUNCTION log_price_change();      -- OLD y NEW guardan ambas versiones

La taxonomía que toda base de datos comparte, según las referencias de PostgreSQL y MySQL: timing — BEFORE (puede modificar NEW o abortar), AFTER (reacciona a la fila confirmada), INSTEAD OF (reemplaza la operación, principalmente en vistas); evento — insert, update, delete; granularidad — nivel de fila versus nivel de sentencia (un update de 10 filas dispara un trigger de fila 10 veces, uno de sentencia una vez). Dos semánticas que vale la pena grabarse: los triggers SQL corren dentro de la misma transacción que la escritura — una falla en el trigger revierte la operación entera — y los triggers AFTER solo se disparan para escrituras que de verdad tuvieron éxito.

Before vs. after: elegidos por el trabajo

Before hooksAfter hooks
Puede cambiar los datos — mutar, aplicar defaults, truncarNo — ya está escrito
Puede abortar la escritura — lanza un error y el save fallaNo
Correcto paraValidación, normalización, campos calculadosContadores, notificaciones, sincronización, auditoría
Incorrecto paraEfectos secundarios — si el save falla después, el efecto ya se disparóCualquier cosa que debió bloquear la escritura
Comportamiento ante fallasRechaza la operación, error al clienteMuchas veces fire-and-forget — los errores caen en los logs
DisciplinaRápido — bloquea cada saveIdempotente — puede correr de nuevo

Los corolarios que ningún explicador enuncia: un efecto secundario en un before-hook es un bug por construcción (el correo sale, y luego el save falla), y un after-hook que no es idempotente es un contador duplicado esperando un reintento. En sistemas de hooks como el de Back4app, afterSave se completa después de que el cliente ya recibió su respuesta — las reacciones son asíncronas por diseño, así que sus fallas deben ser tolerables y quedar en los logs.

Ciclo de vida de la escritura a través de los hooks before y afterUna escritura desde cualquier cliente pasa primero por el hook before, que puede validarla, modificarla o abortarla. Si se permite, la base de datos confirma la escritura, y el hook after reacciona entonces con efectos secundarios como contadores, notificaciones y webhooks, que deben ser idempotentes porque pueden ejecutarse más de una vez.

throw

permite (quizá modificado)

Cualquier cliente
SDK · REST · script

beforeSave
valida · normaliza

Save rechazado —
error al cliente

Escritura confirmada

afterSave
efectos secundarios, idempotentes

Contadores · notificaciones ·
webhooks salientes

Una escritura desde cualquier cliente pasa primero por el hook before, que puede validarla, modificarla o abortarla. Si se permite, la base de datos confirma la escritura, y el hook after reacciona entonces con efectos secundarios como contadores, notificaciones y webhooks, que deben ser idempotentes porque pueden ejecutarse más de una vez.

Hooks vs. triggers SQL

Hooks de aplicación (beforeSave/afterSave)Triggers SQL
LenguajeJavaScript + el SDK y el ecosistema completosSQL / dialectos procedurales de SQL
Llamadas externasSí — APIs, push, webhooksEsencialmente no — y no deberían
Vive enTu código: versionado, testeable, desplegadoEl esquema: dentro de la base de datos
TransacciónLos before-hooks son la puerta de la escritura; los after-hooks corren tras la respuestaLa misma transacción — la falla revierte todo
CubreToda solicitud que pasa por la API del backendToda escritura a la tabla, venga de donde venga
Punto ciegoLas escrituras directas a la base lo esquivanLógica invisible para los debuggers de la aplicación

La última fila es la simetría honesta: la garantía de cada forma está limitada a su capa. Un trigger SQL atrapa hasta una sesión psql renegada, pero esconde lógica del instrumental de la aplicación; un hook a nivel de API cubre todo camino de cliente a través del backend, pero no el acceso crudo a la base — y por eso las plataformas dueñas del gateway de API (todo el tráfico fluye por él) obtienen, en la práctica, lo mejor de ambos. La nota al pie sobre ORMs entra aquí también: los hooks de ORM solo se disparan a través del ORM — las operaciones masivas y el SQL crudo pasan de largo.

Las trampas, con honestidad

La lógica oculta es el clásico: un desarrollador depura su propio código por horas mientras un trigger reescribe valores en silencio — los triggers son invisibles en el punto de llamada, así que documéntalos y mantenlos pocos. Loops infinitos: un trigger que escribe en su propia tabla se vuelve a disparar (y un afterSave que guarda su propio objeto también); protégete comprobando qué cambió, y dale a la recursión una condición de parada antes de que ella encuentre una por ti. Costo síncrono: los before-hooks viven dentro de la latencia de cada escritura — un hook de 200 ms vuelve cada save 200 ms más lento, y las escrituras masivas multiplican los disparos por fila por el número de filas. Cadenas en cascada: triggers que disparan triggers que disparan triggers convierten un insert en un proyecto de arqueología. La regla paraguas de décadas de práctica: los triggers aplican reglas; en el momento en que uno empieza a orquestar un workflow, mueve el workflow a funciones o jobs y deja que el trigger solo encole.

Casos de uso comunes

  • Validación que todo cliente obedece — la regla de estrellas-entre-1-y-5, aplicada por igual contra solicitudes falsificadas y SDKs futuros.
  • Trazas de auditoría — quién cambió qué y cuándo, escritas por el propio evento en lugar de por clientes cooperativos.
  • Contadores desnormalizados y campos calculados — promedios, conteos y duplicados amigables con la búsqueda mantenidos al día en el momento de escribir.
  • Integridad en cascada — rechazar eliminaciones con hijos, o limpiar a los hijos después.
  • Efectos secundarios reactivos — un afterSave que dispara una notificación push o un webhook saliente: el evento de base de datos convertido en evento de integración.

¿Qué hook y dónde? Matriz de decisión

El trabajoEl hook
Rechazar datos malosbeforeSave — lanza un error
Trim, defaults, canonicalizarbeforeSave — muta el objeto
Actualizar un contador o agregadoafterSave — con idempotencia
Notificar a una persona o sistemaafterSave → push / webhook / cola
Bloquear eliminaciones peligrosasbeforeDelete
Limpiar después de eliminarafterDelete
Aplicar alcance de consulta por usuariobeforeFind
Reacción larga o lentaafterSave encola un job — nunca hace el trabajo inline

Limitaciones y trade-offs

  • La invisibilidad es el precio de lo automático. Lógica que nadie llama es lógica que nadie recuerda; nombres, docs y code review mantienen la magia auditable.
  • Los hooks tienen el alcance de su capa. Los hooks de API no ven escrituras directas a la base; los triggers SQL no pierden nada, pero se esconden de tu instrumental — sabe qué punto ciego elegiste.
  • La latencia de escritura es el presupuesto. Todo before-hook gasta de él; mide los hooks como mides las consultas.
  • Los after-hooks son eventualmente consistentes. Los contadores se atrasan milisegundos y pueden dispararse doble — diseña las lecturas (y los reintentos) en consecuencia.
  • Los triggers no reemplazan constraints. Índices únicos, claves foráneas y ACLs se aplican más barato y más temprano; los triggers empiezan donde las reglas declarativas terminan.

Triggers de Base de Datos en Back4app

Back4app es una plataforma open-source de Backend as a Service (BaaS) que combina base de datos gestionada, APIs REST y GraphQL generadas automáticamente, autenticación, almacenamiento de archivos y funciones serverless con Cloud Code. Los triggers aquí son la familia de eventos de datos de Cloud Code: registra Parse.Cloud.beforeSave('Review', …) una vez — las pestañas de código muestran el patrón completo — y la regla aplica a toda escritura que llega por REST, GraphQL, cualquier SDK o el dashboard, porque el gateway de API es el único camino hacia los datos. Los hooks reciben contexto rico (request.object, request.original, request.user, estado de master key), así que la validación puede diferir para admins, beforeFind puede acotar consultas por usuario encima de las ACLs, y los after-hooks tienen todo el ecosistema JavaScript para las reacciones que los triggers SQL no alcanzan — notificaciones push, webhooks salientes, encolado de jobs. Desplegado con tu código, versionado en git, testeable como cualquier función: la garantía del trigger, sin la arqueología del trigger.

Preguntas frecuentes

¿Qué es un trigger de base de datos?

Código procedural que se ejecuta automáticamente cuando un evento de datos — insert, update, delete — ocurre en una tabla o clase específica. La forma clásica vive dentro de la base de datos SQL; la forma moderna, a nivel de aplicación, es una función hook como beforeSave o afterSave que el backend ejecuta alrededor de cada escritura.

¿Cuál es la diferencia entre triggers BEFORE y AFTER?

Capacidad y timing. BEFORE corre antes de la escritura y puede validar, modificar los datos entrantes o abortar la operación por completo. AFTER corre una vez que la escritura tuvo éxito — no puede cambiar lo que pasó, solo reaccionar: registrarlo, contarlo, notificarlo. AFTER nunca se dispara para escrituras que fallaron.

¿Cuál es la diferencia entre un trigger y un stored procedure?

La invocación. Un stored procedure se llama explícitamente, recibe parámetros y devuelve resultados. Un trigger nunca se llama — se dispara automáticamente cuando ocurre su evento, sin parámetros, atado a una tabla. La misma maquinaria procedural, con el modelo de activación opuesto.

¿La lógica debe vivir en triggers o en el código de la aplicación?

El consenso es un híbrido: triggers (o hooks) para reglas que deben cumplirse en todo camino de escritura — validación, integridad, auditoría — y servicios de la aplicación para workflows complejos. Los hooks a nivel de aplicación son el punto medio moderno: garantías de trigger, un lenguaje de programación real y control de versiones.

¿Los triggers perjudican el rendimiento?

Corren de forma síncrona dentro del camino de escritura, así que un trigger lento vuelve lento cada save, y los triggers a nivel de fila se multiplican en operaciones masivas — un update de cien mil filas se dispara cien mil veces. Mantén los before-hooks ligeros y empuja las reacciones lentas a after-hooks o jobs en segundo plano.

¿Un trigger puede causar un loop infinito?

Famosamente — un trigger que escribe en su propia tabla se vuelve a disparar a sí mismo, y un afterSave que guarda el objeto que acaba de procesar entra en recursión hasta que algo se rompe. Protégete comprobando qué cambió de verdad antes de escribir, y nunca vuelvas a guardar el objeto disparador desde su propio after-hook sin una condición de parada.

¿Pueden los triggers llamar a servicios externos?

Los triggers SQL esencialmente no pueden — ni deberían — salir de la base de datos. Esa es la ventaja estelar de los hooks a nivel de aplicación: un afterSave en JavaScript puede enviar una notificación push, llamar a cualquier API o disparar un webhook saliente, porque corre en el proceso del backend con todo el ecosistema disponible.

¿Para qué se usa beforeSave?

Para los tres trabajos que exigen correr antes de la escritura: validación (lanza un error y el save falla, para cualquier cliente), normalización (trim, truncado, canonicalización de campos) y defaults o valores calculados. Los efectos secundarios no van ahí — si el save falla después, el efecto ya ocurrió.

Términos relacionados

Compara con

Lecturas recomendadas

¿Listo para construir tu backend?

Empieza tu proyecto en Back4app en minutos — base de datos, autenticación, APIs y Cloud Code incluidos. Sin tarjeta de crédito.

Escrito y revisado por Back4app Engineering, Back4app Engineering · Publicado el 2026-09-03