fijáis en el asunto de mi e-mail he puesto “a nivel de aplicación”,queriendo decir realizar una transacción en el controlador pero no sobre el modelo de datos, sino a nivel de aplicación.
la verdad es que vi tu mail y la respuesta y pensé que eran transacciones
de db. Esto me pasa por no leer
Más concretamente lo que me interesa es un tema de que el borrado y la generación de la misma caché se realice de forma atómica.
La solución que planteas de encerrar en un begin/rescue/end no me parece
mala, y así a bote pronto no se me ocurre otra forma. Siempre puedes
cambiar el begin por un transaction do y por el mismo precio te llevas
el rollback de base de datos también hecho.
Yo estuve dándole vueltas hace poco a un problema de hacer rollback de
algunas llamadas a métodos de forma automática, pero era en una parte
pequeña de la aplicación y de forma controlada. De hecho no llegué a
implementarlo, aunque no descarto ponerme un día de estos. Era pensando
en hacer migrations un poco más tolerantes a fallos, y lo que se me
ocurría era que todos los métodos que hacían una acción y los métodos
que deshacían esa misma acción compartían el mismo nombre, pero con un
prefijo/sufijo distinto (en mi caso up y down por estar en las
migrations).
Mi plan era al capturar una excepción leer el stack de llamadas de la
aplicación y ver qué métodos se habían ido ejecutando, para llamar en
orden inverso al método contrario (si era un método up llamaría al down,
y si era un down llamaría al up). De esta forma mi rescue sólo tendría
una llamada a “migration_rollback” y no tengo que estar siempre
añadiendo al rescue el procedimiento de back de cada acción, sino que lo
selecciona automáticamente a partir del stack.
Además, esto me permite ejecución condicional. Si no he pasado por un
método concreto no le hago el rollback. De otro modo en el rescue no
tendría forma de saber qué partes tengo que echar atrás y cuáles no.
Si leer del stack me diese muchos problemas (o si no me dejase ir atrás
lo suficiente), había pensado en utilizar set_trace_func y mantener yo
mismo una pila de llamadas en memoria.
De todos modos, como te decía esta idea la tenía pensada para una parte
pequeña y controlada de la aplicación, donde que todos los métodos
tengan su contrario distinguiéndose por nombre es bastante asequible y
donde las operaciones que se están haciendo son limitadas. Y, lo más
importante, no la he puesto en práctica así que puede tener sus pegas
saludos,
javier ramírez