2008-10-13 18 views
20

El marco de aplicación interno que utilizamos en mi empresa hace que sea necesario poner cada consulta SQL en las transacciones, aunque si sé que ninguno de los comandos hará cambios en la base de datos. Al final de la sesión, antes de cerrar la conexión, confirmo la transacción para cerrarla correctamente. Me pregunto si hubo alguna diferencia particular si lo hice retroceder, especialmente en términos de velocidad.¿Hay alguna diferencia entre commit y rollback en una transacción que solo tiene selects?

Tenga en cuenta que estoy utilizando Oracle, pero creo que otras bases de datos tienen un comportamiento similar. Además, no puedo hacer nada sobre el requisito para comenzar la transacción, esa parte de la base de código está fuera de mis manos.

Respuesta

12

Las bases de datos a menudo conservan un diario antes de la imagen (lo que era antes de la transacción) o un diario posterior (lo que será cuando la transacción se complete). Si tiene una imagen anterior, tiene que ser restaurado en un retroceso. Si mantiene una imagen posterior, debe reemplazar los datos en el caso de una confirmación.

Oracle tiene un espacio de diario y de reversión. El diario de transacciones acumula bloques que luego son escritos por escritores de DB. Dado que estos son asíncronos, casi nada relacionado con el escritor DB tiene ningún impacto en su transacción (si la cola se llena, entonces es posible que tenga que esperar)

Incluso para una transacción solo de consulta, estaría dispuesto a apostar que hay un poco de mantenimiento de registros transaccionales en las áreas de reversión de Oracle. Sospecho que una reversión requiere algo de trabajo por parte de Oracle antes de que determine que no hay nada que retractar realmente. Y creo que esto es sincrónico con tu transacción. Realmente no puede liberar ningún bloqueo hasta que se complete la reversión. [Sí, sé que no está utilizando ninguno en su transacción, pero el problema de bloqueo es por qué creo que se debe liberar una reversión, luego se pueden liberar todos los bloqueos y luego se finaliza su retrotracción.]

Activado Por otro lado, el compromiso es más o menos el resultado esperado, y sospecho que descartar el área de restitución podría ser un poco más rápido. No creó entradas de transacción, por lo que el escritor de db nunca se despertará para comprobar y descubrir que no había nada que hacer.

También espero que, si bien la confirmación puede ser más rápida, las diferencias serán menores. Tan de menor importancia, que quizás ni siquiera sea capaz de medirlos en una comparación lado a lado.

+5

No reconozco esto como una descripción de la forma en que funciona Oracle. Parece una descripción genérica que se ha aplicado a Oracle. Las conjeturas sobre cómo funciona Oracle probablemente no sean útiles. –

+0

Oracle llama a la revista "Redo Log File". Llama a los segmentos de retrotracción un "Deshacer tablas". ¿Sabes cuál es más rápido? ¿Comprometerse o revertirse? –

+0

Si no hay trabajo que hacer, es casi seguro que no haya diferencia. Oracle está optimizado para comprometerse rápidamente; solo requiere que el registro de confirmación se escriba en el búfer de registro de rehacer y se vacíe el búfer (excepto para la confirmación asincrónica en 10g +). Una reversión es más trabajo. –

0

Dado que no ha hecho ningún DML, sospecho que no habría diferencia entre COMMIT y ROLLBACK en Oracle. De cualquier manera, no hay nada que hacer.

4

En general, un COMMIT es mucho más rápido que un ROLLBACK, pero en el caso de que no haya hecho nada, es efectivamente el mismo.

8

Estoy de acuerdo con las respuestas anteriores de que no hay diferencia entre COMMIT y ROLLBACK en este caso. Puede haber una diferencia insignificante en el tiempo de CPU necesario para determinar que no hay nada que COMPROMETER contra el tiempo de CPU necesario para determinar que ROLLBACK no tiene nada. Pero, si se trata de una diferencia insignificante, podemos olvidarnos de ello de forma segura.

Sin embargo, vale la pena señalar que hay una diferencia entre una sesión que hace un montón de consultas en el contexto de una sola transacción y una sesión que realiza las mismas consultas en el contexto de una serie de transacciones.

Si un cliente inicia una transacción, realiza una consulta, realiza un RETROCESO COMÚN, luego inicia una segunda transacción y realiza una segunda consulta, no hay garantía de que la segunda consulta observe el mismo estado de la base de datos que la primera consulta. A veces, mantener una sola vista coherente de los datos es esencial. A veces, obtener una visión más actual de los datos es esencial. Depende de lo que está haciendo.

Lo sé, lo sé, el OP no hizo esta pregunta. Pero algunos lectores pueden estar preguntándolo en el fondo de sus mentes.

3

La documentación indica que:

  • Oracle recomienda que se termina de forma explícita cada transacción en sus programas de aplicación con una sentencia COMMIT o ROLLBACK, incluyendo la última transacción, antes de desconectarse de la base de datos de Oracle. Si no compromete explícitamente la transacción y el programa finaliza anormalmente, la última transacción no confirmada se retrotrae automáticamente. Una salida normal de la mayoría de las utilidades y herramientas de Oracle hace que se comprometa la transacción actual. Una salida normal de un programa precompilador de Oracle no compromete la transacción y depende de la base de datos Oracle para deshacer la transacción actual.

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_4010.htm#SQLRF01110

Si desea o optar por hacer una o la otra a continuación, que también podría hacer lo que es lo mismo que no hacer nada, y acaba de cometerlo.

+0

Depende del cliente en realidad. sqlplus, es una confirmación implícita. otros podría no serlo. Si se corta la conexión de red (p. Ej., El cliente simplemente "desaparece"), se produce una reversión. –

+0

No estoy seguro de que no dependa de la aplicación, probablemente debería haber dicho una "desconexión elegante", pero los documentos dicen que "se produce una solicitud implícita después de la finalización normal de una aplicación o ..." http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/transact.htm # CNCPT1119 –

+0

En realidad, encontré una mejor referencia y edité mi publicación. Gracias. –

1

Bueno, debemos tener en cuenta qué devuelve SELECT en Oracle. Hay dos modos. Por defecto, un SELECT devuelve los datos tal como se veían esos datos en el mismo momento en que la instrucción SELECT comenzó a ejecutarse (este es el comportamiento predeterminado en el modo de aislamiento READ COMMITTED, el modo transaccional predeterminado). Entonces, si se ejecutó UPDATE/INSERT después de que se emitió SELECT, eso no estará visible en el conjunto de resultados.

Esto puede ser un problema si necesita comparar dos conjuntos de resultados (por ejemplo, los lados de debta y crédito de una aplicación de libro mayor). Para eso tenemos un segundo modo. En ese modo, SELECT devuelve los datos tal como se veían en el momento en que comenzó la transacción actual (comportamiento predeterminado en READ SOLO y niveles de aislamiento SERIALIZABLES).

Por lo tanto, al menos algunas veces es necesario ejecutar SELECT en la transacción.

0

Creo que un Commit sería más eficiente; ya que generalmente esperaría que la mayoría de las transacciones DB se comprometieran; por lo que podría pensar que la base de datos se optimiza para este caso (en lugar de intentar ser más eficiente para una reversión).

Cuestiones relacionadas