descargar - oracle software
Transacción bidimensional/transacción compartida (5)
El escenario es este
Tenemos dos aplicaciones A y B, que se ejecutan en transacciones de bases de datos separadas (Oracle 9i)
Aplicación A: inserta algunos datos en la base de datos, luego llama a la aplicación B, aplicación B, inserta algunos datos en la base de datos, relacionados (a través de claves externas) con los datos de A. Devuelve un "ID" a la Aplicación A: A usa ID para insertar más datos, incluida la ID de B
Ahora, como se trata de transacciones separadas, pero ambas dependen de los datos de las transacciones de los demás, debemos comprometernos entre las llamadas a cada aplicación. Esto, por supuesto, hace que sea muy difícil retroceder si algo sale mal.
¿Cómo abordaría este problema con una mínima refacturación del código? Sin duda, este tipo de esto es un problema común en el mundo SOA?
------ Actualizar --------
No he podido encontrar nada en Oracle 9i, sin embargo Oracle 11g proporciona DBMS_XA , que hace exactamente lo que yo buscaba .
Algunas sugerencias:
Use las transacciones de Compensación . Básicamente, permite deshacer la transacción que hizo anteriormente. La parte difícil es descubrir qué transacciones revertir.
Confirme los datos de las aplicaciones A y B con una bandera que indique que solo es temporal. Luego, después de que todo sale bien, modifique la bandera para indicar que los datos son finales. Durante la noche, ejecute un trabajo por lotes para eliminar los datos que no se han finalizado.
Me gustan las dos soluciones presentadas, así que evité publicar esto por un tiempo. Pero también podría hacer una actualización de la tabla principal, habiendo guardado previamente el estado de las filas afectadas en algún caché.
Esto podría combinarse con el de dos niveles (el sistema de policía de tráfico propuesto por Zathrus), porque realmente no sería necesario para la solución de neonski de usar una tabla o tablas de "bloc de dibujo". El inconveniente de esto es que tendría que tener sus procs / lógica consultando la tabla principal del área de trabajo o el área de trabajo de la tabla principal, o tal vez almacenar su marca en la tabla principal y volver a establecerla cuando se comprometan los datos a la mesa principal.
Una dama de nuestro equipo está diseñando algo así para nuestro sistema en tiempo real, utilizando tablas de trabajo permanentes.
Probablemente pueda insertar los datos de la Aplicación A en un área ''temporal'' para que la Aplicación B pueda hacer las inserciones de A y B sin cambiar mucho en cualquiera de las aplicaciones. No es particularmente elegante, pero podría hacer el truco.
En otro caso, puede agregar un campo de indicador de "confirmación" a sus datos, que se actualiza después de que todo el proceso se haya ejecutado correctamente. Si falla en un punto, podría ser más fácil rastrear los registros que necesita revertir (en efecto, eliminar).
Tienes tres opciones:
Rediseñe la aplicación para que no tenga dos procesos diferentes (ambos con conexiones de base de datos) escribiendo en la base de datos y transfiéralo a una sola aplicación.
Cree la aplicación C que maneja todas las transacciones de la base de datos para A y B.
Tira tu propia confirmación de dos fases. La aplicación C actúa como coordinador. C señala A y B para preguntar si están listos para comprometerse. A y B procesan y responden a C con una respuesta "preparada" o "fallida" (tenga en cuenta que debe haber un tiempo de espera en C para evitar una espera infinita si un proceso se bloquea o muere). Si ambas respuestas están listas, entonces C les dice que se comprometan. De lo contrario, envía una señal de retroceso.
Tenga en cuenta que puede tener problemas con la opción 3 si la aplicación A confía en las claves externas de la aplicación B (que no indicó, por lo que puede no ser un problema). La coherencia de lectura de Oracle probablemente evitará que esto se permita, ya que la transacción de la aplicación A comenzará antes de la aplicación B. Solo una advertencia.
App_A =={0}=> database # App_A stores information for App_B
App_A ------> App_B # App_A starts App_B
App_B <={0}== database # App_B retrieves the information
App_B =={1}=> database # App_B stores more informaion
App_A <={2}== App_B # App_B returns ''ID'' to App_A
App_A ={2,3}> database # App_A stores ''ID'' and additional data
¿Soy solo yo o parece que la Aplicación B es esencialmente solo una subrutina de A. Me refiero a que la Aplicación B no hace nada hasta que A lo pide, y la Aplicación A no hace nada hasta que B devuelve una ID. Lo que significa que tiene poco sentido tenerlos en diferentes aplicaciones, o incluso separar hilos.