sql >> Base de Datos >  >> RDS >> Oracle

Tengo un disparador autónomo pero solo ejecuto una vez en la misma sesión

Está utilizando una transacción autónoma para solucionar el hecho de que un disparador no puede consultar su tabla en sí. Se encontró con el infame error de la tabla de mutación y descubrió que declarar el disparador como una transacción autónoma hace que el error desaparezca.

Sin embargo, no tuvo suerte, esto no resuelve el problema en absoluto:

  • Primero, se pierde cualquier lógica de transacción. No puede deshacer los cambios en el suscription_fact mesa, están comprometidos , mientras que su transacción principal no es y podría revertirse. Así que también ha perdido la integridad de sus datos.
  • ¡El disparador no puede ver la nueva fila porque la nueva fila aún no se ha confirmado! Dado que el activador se ejecuta en una transacción independiente, no puede ver los cambios no confirmados realizados por la transacción principal:se encontrará con resultados completamente erróneos.

Es por eso que nunca debe hacer ninguna lógica comercial en transacciones autónomas. (existen aplicaciones legítimas, pero se limitan casi por completo al registro/depuración).

En su caso, debe:

  1. Actualice su lógica para que no necesite consultar su tabla (actualizando suscription_fact solo si la nueva fila es más reciente que el valor anterior almacenado en id_date_unsuscription ).
  2. Olvídese de usar la lógica de negocios en los disparadores y use un procedimiento que actualice todas las tablas correctamente o use una vista porque aquí tenemos un caso claro de datos redundantes.
  3. Utilice una solución alternativa que realmente funcione (por Tom Kyte) .

Recomiendo encarecidamente usar (2) aquí. No utilice activadores para codificar la lógica empresarial. Son difíciles de escribir sin errores y aún más difíciles de mantener. El uso de un procedimiento garantiza que todo el código relevante esté agrupado en un solo lugar (un paquete o un procedimiento), fácil de leer y seguir y sin consecuencias imprevistas.