2009-10-03 7 views
6

En este momento el proceso que estamos utilizando para insertar conjuntos de registros es algo como esto:¿Puedo sustituir puntos de rescate por iniciar nuevas transacciones en Oracle?

(y tenga en cuenta que "conjunto de registros" significa algo así como el registro de una persona junto con sus direcciones, números de teléfono o cualquier otras tablas unidas).

  1. Comenzar una transacción.
  2. Inserta un conjunto de registros que están relacionados.
  3. Comprométete si todo fue exitoso, deshazte de lo contrario.
  4. Regrese al paso 1 para el siguiente conjunto de registros.

¿Deberíamos estar haciendo algo más como esto?

  1. iniciar una transacción al principio de la secuencia de comandos
  2. Iniciar un punto de guardado para cada conjunto de registros.
  3. Inserta un conjunto de registros relacionados.
  4. Retroceda al punto de guardado si hay un error, continúe si todo es exitoso.
  5. Confirme la transacción al comienzo de la secuencia de comandos.

Después de tener algunos problemas con ORA-01555 y la lectura de algunos artículos (Pregunta a Tom como this one), estoy pensando en probar el segundo proceso. Por supuesto, como señala Tom, comenzar una nueva transacción es algo que debería ser definido por las necesidades del negocio. ¿Vale la pena probar el segundo proceso o es una mala idea?

+1

+1, pregunta interesante (también para la discusión de abajo) – DCookie

+0

Sería útil si coloca su valor actual para UNDO_RETENTION y el tiempo necesario para que se ejecute el script completo y el procesamiento de cada conjunto. –

Respuesta

5

Una transacción debe ser una unidad de trabajo significativa. Pero lo que constituye una Unidad de Trabajo depende del contexto. En un sistema OLTP, una unidad de trabajo sería una sola persona, junto con su información de dirección, etc. Pero parece que está implementando alguna forma de procesamiento por lotes, que está cargando muchas personas.

Si tiene problemas con ORA-1555, es casi seguro que tenga una consulta de larga ejecución que suministre datos que estén siendo actualizados por otras transacciones. Comprometerse dentro de su bucle contribuye al uso cíclico de los segmentos UNDO, y por lo tanto tenderá a aumentar la probabilidad de que los segmentos en los que confía proporcionen consistencia de lectura hayan sido reutilizados. Entonces, no hacer eso es probablemente una buena idea.

Si se usa SAVEPOINTs, la solución es una cuestión diferente. No estoy seguro de qué ventaja le daría en su situación. Como está trabajando con Oracle10g, quizás deba considerar el uso masivo de DML error logging.

O bien, puede que desee volver a escribir la consulta de conducción para que funcione con trozos de datos más pequeños. Sin saber más sobre los detalles de su proceso, no puedo dar consejos específicos. Pero, en general, en lugar de abrir un cursor para 10.000 registros, sería mejor abrirlo veinte veces para 500 filas cada vez. La otra cosa a considerar es si el proceso de inserción se puede hacer más eficiente, por ejemplo, utilizando la recopilación masiva y FORALL.

+0

+1 para la confirmación dentro de un bucle. Por lo general, esto ocurre cuando actualiza los registros que está seleccionando en el ciclo. Todavía se reduce para deshacer la retención y el tamaño. Vea otro enlace de Burleson (que hace referencia a otros): http://www.dba-oracle.com/t_ora_01555_snapshot_old.htm – DCookie

+0

La ventaja de los puntos de rescate sería que, al no comprometer a Oracle, se vería obligado a retener la información en UNDO por más tiempo. Sospecho que a su esquema le falta un paso 0 de "Abrir un cursor". En el método original, puede perder el deshacer cada vez que llega al paso 3, por lo que el cursor del paso 0 puede aumentar 1555. En el nuevo método, debe deshacer el deshacer hasta el final del script. –

1

Algunos pensamientos ...

  1. Me parece que uno de los puntos de enlace de la asktom era el tamaño de su reversión/deshacer adecuadamente para evitar la década de 1555. ¿Hay alguna razón por la que esto no es posible? Como él señala, es mucho más barato comprar un disco que escribir/mantener código para manejar las limitaciones de reversión (aunque tuve que hacer una doble toma después de leer la etiqueta de precio de $ 250 para una unidad de 36 Gb, ese hilo comenzó en 2002 ! Buen ejemplo de la Ley de Moore!)
  2. This link (Burleson) muestra un posible problema con puntos de guardado.
  3. ¿Es su transacción en realidad los pasos 2,3 y 5 en su segundo escenario? Si es así, eso es lo que haría: comprometer cada transacción. Me parece un poco como el escenario 1 es una colección de transacciones en uno solo?
+0

Creo que podría no haber sido lo suficientemente claro en el primer escenario. Básicamente, en este momento nos comprometemos con cada conjunto de registros (por conjunto de registros me refiero a algo así como decir una persona, sus direcciones y números de teléfono). Lo que estaba pensando era hacer esto más como una gran transacción que usa puntos de rescate. –

+0

No veo por qué estás recibiendo 1555 entonces. ¿Qué estás tratando de obtener de los puntos de rescate? Me parece que es más probable que obtenga los 1555 errores en el segundo escenario? – DCookie

+0

Si se comete con frecuencia, los registros se dispersarán por varios segmentos de deshacer. Esto hace que sea más probable que las transacciones se sobrescriban y aumente la probabilidad de un ORA-01555. De hecho, las confirmaciones más frecuentes ocupan * más * espacio de deshacer: http://oradbdev.blogspot.com/2007/04/commit-frequency-and-undo.html –

Cuestiones relacionadas