Respuestas a más preguntas sobre transacciones (3)

2 comentarios

Aquí están las respuestas correctas, y sus respectivas explicaciones, al artículo: Más preguntas sobre transacciones (3)

Así que veamos que tal te fue:

Pregunta 1. ¿Dentro de un stored procedure se puede escribir un COMMIT?

[Sí]     [No]     [Sí, en un EXECUTE STATEMENT]

La respuesta es Sí, en un EXECUTE STATEMENT. Pero el hecho de que pueda hacerse no significa que deba hacerse, es una posibilidad que tenemos pero debemos pensar muy bien antes de emplearla.

Pregunta 2. ¿Dentro de un trigger se puede escribir un COMMIT?

[Si]     [No]     [Sí, en un EXECUTE STATEMENT]

La respuesta es Sí, en un EXECUTE STATEMENT. Misma respuesta que en la Pregunta 1.

Pregunta 3. ¿Las instrucciones dentro de un IN AUTONOMOUS TRANSACTION DO requieren que la transacción finalice con un COMMIT para confirmarse?

[Sí]     [No]     [A veces]

La respuesta es No. Como su nombre lo indica se trata de una transacción autónoma que siempre finaliza automáticamente con un COMMIT.

Por lo tanto, todo lo que escribamos dentro de IN AUTONOMOUS TRANSACTION DO siempre estará confirmado.

Pregunta 4. ¿Se puede crear una tabla dentro de un stored procedure?

[Sí]     [No]     [Sí, si se usa EXECUTE STATEMENT]

La respuesta es Sí, si se usa EXECUTE STATEMENT. Pero mucho cuidado, el hecho de que pueda hacerse no significa que deba hacerse. Si creas un tabla dentro de un stored procedure el Firebird solamente podrá comprobar que su estructura es correcta cuando se ejecute ese stored procedure. Eso significa que podrías haber escrito el nombre de un dominio inexistente o cualquier otro error y será detectado recién cuando el stored procedure sea ejecutado…quizás por un usuario de muy pocas pulgas.

Pregunta 5. Si una transacción solamente hizo un SELECT. ¿Es preferible que esa transacción finalice con un COMMIT o con un ROLLBACK?

[Con un COMMIT]     [Con un ROLLBACK]     [Es indiferente]

La respuesta es Con un COMMIT. ¿Por qué? Porque el resultado final será el mismo si finalizas esa transacción con un COMMIT o con un ROLLBACK, pero el COMMIT es más rápido que el ROLLBACK y por lo tanto lo preferible es que finalices esa transacción con un COMMIT.

Como la transacción solamente hizo un SELECT, no dejó basura en la Base de Datos, pero el COMMIT es más rápido que el ROLLBACK.

Pregunta 6. ¿Una transacción puede saber lo que las otras transacciones están haciendo?

[Sí]     [No]     [A veces]

La respuesta es No. Jamás en Firebird una transacción puede saber lo que las otras transacciones están haciendo, solamente puede saber:

  • Lo que hicieron las transacciones que finalizaron con un COMMIT antes de que ella empezara
  • Si su aislamiento es READ COMMITED, lo que hicieron las transacciones que ya finalizaron con un COMMIT (aunque hubieran empezado después que ella)
  • Lo que ella misma ha hecho

Firebird cumple al 100% con ACID y por lo tanto cada transacción está totalmente aislada de las demás transacciones, nunca una transacción podría saber lo que las demás transacciones están haciendo, solamente puede  saber lo que otras transacciones que ya finalizaron con un COMMIT hicieron.

Artículos relacionados:

Más preguntas sobre transacciones (3)

Creando tablas dentro de un stored procedure o de un trigger

Crear una tabla e insertarle filas DENTRO de un stored procedure

Terminar las transacciones de los SELECTs

El índice del blog Firebird21

El foro del blog Firebird21

00

Anuncios

Más preguntas sobre transacciones (3)

2 comentarios

Este tema de las transacciones es de suma importancia en Firebird, porque todo lo que hagamos, sí o sí, se realiza dentro de una transacción, así que debemos entenderlas muy bien.

Por lo tanto, para que puedas auto-evaluarte, aquí hay más preguntas:

Pregunta 1. ¿Dentro de un stored procedure se puede escribir un COMMIT?

[Sí]     [No]     [Sí, en un EXECUTE STATEMENT]

Pregunta 2. ¿Dentro de un trigger se puede escribir un COMMIT?

[Si]     [No]     [Sí, en un EXECUTE STATEMENT]

Pregunta 3. ¿Las instrucciones dentro de un IN AUTONOMOUS TRANSACTION DO requieren que la transacción finalice con un COMMIT para confirmarse?

[Sí]     [No]     [A veces]

Pregunta 4. ¿Se puede crear una tabla dentro de un stored procedure?

[Sí]     [No]     [Sí, si se usa EXECUTE STATEMENT]

Pregunta 5. Si una transacción solamente hizo un SELECT. ¿Es preferible que esa transacción finalice con un COMMIT o con un ROLLBACK?

[Con un COMMIT]     [Con un ROLLBACK]     [Es indiferente]

Pregunta 6. ¿Una transacción puede saber lo que las otras transacciones están haciendo?

[Sí]     [No]     [A veces]

NOTA: Solamente responde con una de las opciones disponibles, sin dar explicaciones, porque las respuestas correctas y sus respectivas explicaciones aparecerán en otro artículo, dentro de dos días. Si das explicaciones, podrías “avivar” a los demás y esa no es la idea, la idea es que cada quien pueda auto-evaluarse.

Artículos relacionados:

3 preguntas sobre transacciones

Respuestas a las 3 preguntas sobre transacciones

Más preguntas sobre transacciones (2)

Respuestas a más preguntas sobre transacciones (2)

El índice del blog Firebird21

El foro del blog Firebird21

Respuestas a más preguntas sobre transacciones (2)

Deja un comentario

¿Has respondido a las preguntas hechas en el artículo: Más preguntas sobre transacciones (2)?

Si lo has hecho, ¡¡¡excelente!!! porque sirven para auto-evaluarte. Hay que participar.

Veamos ahora cuales son las respuestas correctas.

Pregunta 1. ¿Cuántas transacciones como máximo puede tener una Base de Datos?

[100.000.000]     [1.000.000.000]     [2.147.483.647]      [No hay límite]

La respuesta es 2.147.483.647. ¿Por qué? Porque el número que identifica a las transacciones se guarda como “signed integer” en las versiones de Firebird hasta las 2.5.x, (a partir de la versión 3.0 se guardará como un “unsigned integer”), así que en el momento de escribir este artículo se usa “signed integer”. Firebird está escrito en el lenguaje C++ y en ese lenguaje un número entero se guarda en 4 bytes. Y como 4 bytes equivale a 32 bits entonces la cantidad de valores distintos es 2 ^ 32 que es igual a 4.294.967.296, la mitad de ellos positivos y la otra mitad negativos. Pero como Firebird usa “signed integer”, es decir, enteros con signo, solamente se consideran el cero y los números positivos. El cero no se usa para identificar transacciones y por lo tanto, el mayor número posible de transacciones en una Base de Datos es 2.147.483.647

Algo importante a tener en cuenta es que cuando la Next Transaction ya está muy cerca de ese número hay que realizar un ciclo backup/restore para que se reinicie y así tener otras 2.147.483.000 transacciones disponibles.

Pregunta 2. Después de realizar un ciclo backup/restore con el programa GBAK, ¿cuál es el valor de Next Transaction en la Base de Datos restaurada?

[0]     [1]     [2]     [3]     [1.000]     [Es variable]

La respuesta: es variable. Aunque en general es menor que 1.000. Cuando se empieza a realizar un restore la Next Transaction se inicializa en 1. Pero la restauración requiere de varias transacciones así que cuando la restauración finaliza el valor de Next Transaction es bastante mayor que 1. Normalmente anda alrededor de 300. También depende de si se escribió la opción -verbose o no, porque si se la escribió, cada índice restaurado necesitará de una nueva transacción.

Así que por lo general, salvo que tengas una Base de Datos gigantesca, el valor de la Next Transaction al finalizar el restore será mayor que 1 y menor que 1.000

Pregunta 3. Si una transacción T1 finalizó con un ROLLBACK e inmediatamente después se inició una transacción T2. Esta transacción T2 ¿tendrá el mismo número que la transacción T1 o un número diferente?

[El mismo número]     [Un número diferente]

Todas las transacciones tienen un número diferente. Jamás dos transacciones podrían tener el mismo número en una Base de Datos porque ese número sirve para identificarlas y evidentemente si dos transacciones tuvieran el mismo número no se podría diferenciarlas.

Pregunta 4. Si una transacción realizó un UPDATE y después finalizó con un COMMIT. ¿Dejó basura en la Base de Datos?

[Sí]     [No]

La respuesta es . Todas las operaciones de UPDATE y de DELETE dejan basura en la Base de Datos sin importar si la transacción finalizó con un COMMIT o con un ROLLBACK porque en ambos casos dejan basura.

En general el Firebird es muy bueno recolectando la basura dejada por las transacciones que finalizaron con un COMMIT entonces no tardará en eliminar esa basura, pero la transacción sí dejó basura.

Pregunta 5. Si una transacción realizó un UPDATE y después finalizó con un ROLLBACK. ¿Dejó basura en la Base de Datos?

[Sí]     [No]

La respuesta es . Todas las operaciones de UPDATE y de DELETE dejan basura en la Base de Datos sin importar si la transacción finalizó con un COMMIT o con un ROLLBACK porque en ambos casos dejan basura.

La basura dejada por los ROLLBACK se elimina cuando se realiza un sweep.

Artículos relacionados:

Más preguntas sobre transacciones (2)

Entendiendo los identificadores de las transacciones

La Next Transaction después de un ciclo backup/restore

Entendiendo sweep y garbage collection

El índice del blog Firebird21

El foro del blog Firebird21

Más preguntas sobre transacciones (2)

6 comentarios

Ya has podido auto-evaluar algunos de tus conocimientos sobre transacciones en el artículo: 3 preguntas sobre transacciones y las respuestas correctas las pudiste ver en el artículo: Respuestas a las 3 preguntas sobre transacciones.

¿Qué tal te fue?

Para continuar con el tema, aquí hay más preguntas.

Pregunta 1. ¿Cuántas transacciones como máximo puede tener una Base de Datos?

[100.000.000]     [1.000.000.000]     [2.147.483.647]      [No hay límite]

Pregunta 2. Después de realizar un ciclo backup/restore con el programa GBAK, ¿cuál es el valor de Next Transaction en la Base de Datos restaurada?

[0]     [1]     [2]     [3]     [1.000]     [Es variable]

Pregunta 3. Si una transacción T1 finalizó con un ROLLBACK e inmediatamente después se inició una transacción T2. Esta transacción T2 ¿tendrá el mismo número que la transacción T1 o un número diferente?

[El mismo número]     [Un número diferente]

Pregunta 4. Si una transacción realizó un UPDATE y después finalizó con un COMMIT. ¿Dejó basura en la Base de Datos?

[Sí]     [No]

Pregunta 5. Si una transacción realizó un UPDATE y después finalizó con un ROLLBACK. ¿Dejó basura en la Base de Datos?

[Sí]     [No]

Artículos relacionados:

3 preguntas sobre transacciones

Respuestas a las 3 preguntas sobre transacciones

El índice del blog Firebird21

El foro del blog Firebird21

Respuestas a las 3 preguntas sobre transacciones

2 comentarios

En el artículo: 3 preguntas sobre transacciones habías podido auto-evaluarte para comprobar tu entendimiento sobre las transacciones del Firebird. ¿Sabes cuáles son las respuestas correctas?. Veamos:

Pregunta 1. Una transacción realizó tres inserciones. El tercer INSERT elevó una excepción. ¿Es posible finalizar esa transacción con un COMMIT exitoso?

[Sí]   [No]

La respuesta es . El COMMIT y el ROLLBACK no dependen de las excepciones. Las excepciones son los mensajes de error que el Servidor le envía al Cliente para informarle de que algo está mal. Y lo normal por supuesto es hacer el COMMIT solamente a las transacciones que no elevaron una excepción pero eso no es obligatorio.

Veamos un ejemplo: Tenemos una tabla llamada BANCOS con estas filas:

TRANSACCION1

Captura 1. Si haces clic en la imagen la verás más grande

Donde la columna BAN_IDENTI es la Primary Key y por lo tanto no puede repetirse, pero escribimos:

Listado 1.

INSERT INTO BANCOS (BAN_IDENTI, BAN_NOMBRE) VALUES(3, 'BANCO NRO 3');
INSERT INTO BANCOS (BAN_IDENTI, BAN_NOMBRE) VALUES(1, 'BANCO REPETIDO');

Y el Firebird nos responde con el mensaje: ‘Violation of PRIMARY or UNIQUE KEY constraint “PK_BANCOS” on table “BANCOS”. Problematic key value is (“BAN_IDENTI” = 1).’

El segundo INSERT falló porque quisimos poner en la columna BAN_IDENTI un valor que ya existía en esa columna, algo que no está permitido. Sin embargo, ¿podemos finalizar esa transacción con un COMMIT?

Listado 2.

COMMIT

Pues sí, sin problema. Aceptó el COMMIT. La fila cuyo valor de BAN_IDENTI estaba repetido no fue insertada, pero la transacción igualmente finalizó con un COMMIT. ¿Y qué pasó con la primera fila, fue insertada o no? Veamos.

Listado 3.

SELECT
   BAN_IDENTI,
   BAN_NOMBRE
FROM
   BANCOS

TRANSACCION2

Captura 2. Si haces clic en la imagen la verás más grande

Pues sí, fue insertada. La fila no insertada fue la que tenía problemas, la fila que estaba correcta fue insertada.

En general, lo normal (y la mayor parte de las veces lo correcto) es que si una transacción eleva una excepción se finalice esa transacción con un ROLLBACK, pero también podemos finalizarla con un COMMIT, como acabamos de ver. En este caso, las instrucciones que no elevaron una excepción y que se ejecutaron antes de la que elevó la excepción serán confirmadas.

Cambiemos el orden de los INSERT y veamos que ocurre:

Listado 4.

INSERT INTO BANCOS (BAN_IDENTI, BAN_NOMBRE) VALUES(1, 'BANCO REPETIDO');
INSERT INTO BANCOS (BAN_IDENTI, BAN_NOMBRE) VALUES(3, 'BANCO NRO 3');

En este caso, como fue el primer INSERT el que elevó la excepción, el segundo INSERT jamás se ejecutará y nuestra tabla de BANCOS quedará sin modificarse.

TRANSACCION1

Captura 3. Si haces clic en la imagen la verás más grande

La Captura 3. nos muestra como quedó la tabla de BANCOS después de ejecutar el Listado 4., o sea que como el primer INSERT falló, el segundo INSERT nunca se ejecutó y la tabla de BANCOS quedó exactamente igual a como estaba antes.

Pregunta 2. La tabla MiTabla tiene 10 filas. Simultáneamente 3 transacciones se iniciaron y cada transacción insertó una fila en MiTabla. En la tercera transacción se escribió:

Listado 5.

SELECT
   COUNT(*)
FROM
   MiTabla

¿Cuál será el resultado mostrado?

[10]    [11]    [12]    [13]

El resultado será 11. Al iniciarse cada transacción para ella la tabla MiTabla tiene 10 filas. Una transacción no puede saber lo que las demás transacciones están haciendo.  Pero sí sabe muy bien lo que ella misma está haciendo. Entonces, para la tercera transacción inicialmente MiTabla tenía 10 filas, le insertó una fila y por lo tanto al escribir el SELECT obtendrá el resultado de 11. Las 10 filas iniciales más la fila que ella insertó.

Pregunta 3. Tenemos un generador cuyo nombre es MiGenerador y su valor es 10. Dos transacciones, T1 y T2, se están ejecutando simultáneamente. En la transacción T1 ejecutamos: GEN_ID(MiGenerador, 1) y en la transacción T2 ejecutamos: GEN_ID(MiGenerador, 1)

La transacción T1 finalizó con un COMMIT y la transacción T2 finalizó con un ROLLBACK. ¿Cuál es el valor de MiGenerador después de eso?

[10]    [11]    [12]

El valor de MiGenerador es 12. Los generadores (también llamados secuencias) están afuera de las transacciones, no importa como finalice una transacción, si con COMMIT o con ROLLBACK, eso no les afecta a los generadores.

Entonces, MiGenerador tenía un valor inicial de 10, la primera función GEN_ID() en ejecutarse lo incrementó a 11 y la segunda función GEN_ID() en ejecutarse lo incrementó a 12.

Artículos relacionados:

3 preguntas sobre transacciones

El índice del blog Firebird21

El foro del blog Firebird21

3 preguntas sobre transacciones

9 comentarios

Como seguramente sabes, en Firebird el correcto entendimiento de las transacciones es extremadamente importante y si no las entiendes bien el resultado será predecible: harás mal tus tareas.

No hay alternativa.

O entiendes como funcionan las transacciones en Firebird o no entiendes. Y si no entiendes, tendrás problemas.

Así que aquí hay un pequeño examen para que puedas autoevaluarte y verificar si entiendes o no como funcionan las transacciones en Firebird.

Pregunta 1. Una transacción realizó tres inserciones. El tercer INSERT elevó una excepción. ¿Es posible finalizar esa transacción con un COMMIT exitoso?

[Sí]   [No]

Pregunta 2. La tabla MiTabla tiene 10 filas. Simultáneamente 3 transacciones se iniciaron y cada transacción insertó una fila en MiTabla. En la tercera transacción se escribió:

Listado 1.

SELECT
   COUNT(*)
FROM
   MiTabla

¿Cuál será el resultado mostrado?

[10]    [11]    [12]    [13]

Pregunta 3. Tenemos un generador cuyo nombre es MiGenerador y su valor es 10. Dos transacciones, T1 y T2, se están ejecutando simultáneamente. En la transacción T1 ejecutamos: GEN_ID(MiGenerador, 1) y en la transacción T2 ejecutamos: GEN_ID(MiGenerador, 1)

La transacción T1 finalizó con un COMMIT y la transacción T2 finalizó con un ROLLBACK. ¿Cuál es el valor de MiGenerador después de eso?

[10]    [11]    [12]

Artículos relacionados:

Entendiendo a las transacciones

El índice del blog Firebird21

El foro del blog Firebird21

Presentación sobre transacciones de Alexey Kovyazin

2 comentarios

Alexey Kovyazin de la empresa IBSurgeon es una de las personas que más conoce sobre Firebird en todo el mundo, lo que él dice es “palabra mayor” en ese tema. Tengo entendido que es ruso y vive en Moscú.

En Brasil, todos los años se celebra lo que se conoce como Firebird Developers Day o sea el día para los desarrolladores de Firebird.

En la edición número 11 del Firebird Developers Day hubo una presentación de Alexey Kovyazin que puede ser vista en:

Explica de manera magistral lo que son las transacciones, como funcionan, la importancia de los indicadores, por qué las transacciones deben ser cortas, etc.

El material está escrito enteramente en inglés, pero es bastante fácil de entender.

Es altamente recomendable que lo leas, quizás varias veces, hasta que comprendas todo perfectamente porque un buen entendimiento y manejo de las transacciones es fundamental en Firebird.

Si después de leerlo tienes alguna duda, puedes ingresar al foro de este blog y hacer allí todas tus preguntas.

NOTA: Para ver esta presentación en pantalla completa, haz clic sobre el icono que tiene flechas inclinadas y que se encuentra abajo y a la derecha de la presentación.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Older Entries Newer Entries