Pregunta

Parece haber opiniones muy diferentes sobre el uso de transacciones para leer desde una base de datos.

Cita del artículo de DeveloperWorks Estrategias de transacción: modelos y resumen de estrategias :

  

¿Por qué necesitarías una transacción si   solo estás leyendo datos? La respuesta   es que no lo haces Comenzando un   transacción para realizar una solo lectura   la operación se suma a la sobrecarga de la   subproceso de procesamiento y puede causar compartido   leer bloqueos en la base de datos (dependiendo   sobre qué tipo de base de datos está utilizando   y cuál es el nivel de aislamiento establecido   a).

Como opinión contraria, existe la siguiente cita de la documentación de Hibernate Acceso a datos no transaccionales y confirmación automática modo

  

Nuestra recomendación es no usar el   modo de confirmación automática en una aplicación, y   para aplicar solo transacciones de solo lectura   cuando hay un rendimiento obvio   beneficio o cuando cambia el código futuro   son altamente improbables Siempre prefiero   transacciones regulares de ACID para agrupar   sus operaciones de acceso a datos,   independientemente de si lees o   escribir datos.

También hay un debate similar sobre la lista de correo de EclipseLink aquí .

Entonces, ¿dónde está la verdad? ¿Son las transacciones para leer las mejores prácticas o no? Si ambas son soluciones viables, ¿cuáles son los criterios para utilizar las transacciones?

Hasta donde puedo ver, solo hace una diferencia si el nivel de aislamiento es más alto que 'lectura comprometida'. ¿Es esto correcto?

¿Cuáles son las experiencias y recomendaciones?

¿Fue útil?

Solución

Steven Devijver proporcionó algunas buenas razones para iniciar transacciones, incluso si las operaciones solo van a leer la base de datos:

  • Establecer tiempos de espera o modos de bloqueo
  • Establecer nivel de aislamiento

SQL estándar requiere que incluso una consulta debe iniciar una nueva transacción si no hay ninguna transacción actualmente en curso. Hay DBMS donde eso no es lo que sucede: aquellos con un modo de confirmación automática, por ejemplo (la declaración inicia una transacción y la confirma inmediatamente cuando se completa la declaración). Otros DBMS hacen declaraciones atómicas (efectivamente autocomprometidas) de manera predeterminada, pero inician una transacción explícita con una declaración como 'COMENZAR A TRABAJAR', cancelando la confirmación automática hasta el próximo COMPROMISO o ROLLBACK (IBM Informix Dynamic Server es uno de esos) cuando la base de datos no está MODE ANSI).

No estoy seguro sobre el consejo de nunca retroceder. No hace ninguna diferencia en la transacción de solo lectura y, en la medida en que molesta a sus DBA, es mejor evitar ROLLBACK. Pero si su programa sale sin hacer un COMPROMISO, el DBMS debe hacer un ROLLBACK en su transacción incompleta, ciertamente si modificó la base de datos e (por simplicidad) incluso si solo seleccionó datos.

En general, si desea cambiar el comportamiento predeterminado de una serie de operaciones, use una transacción, incluso si la transacción es de solo lectura. Si está satisfecho con el comportamiento predeterminado, no es crucial utilizar una transacción. Si su código debe ser portátil entre DBMS, es mejor asumir que necesitará una transacción.

Otros consejos

Primero, esto suena como una optimización prematura. Como Steven señaló, la mayoría de las bases de datos sensatas lo llevarán a una transacción de todos modos, y todo lo que realmente están haciendo es llamar a commit después de cada declaración. Entonces, desde esa perspectiva, la confirmación automática puede ser menos eficaz ya que cada declaración tiene que comenzar una nueva transacción. O tal vez no. Solo la evaluación comparativa lo dirá y apuesto a que no hace una gran diferencia en su aplicación.

Una razón por la que desea utilizar siempre una transacción es la coherencia de la protección. Si comienza a jugar con declarar manualmente una transacción solo cuando '' necesita '' entonces te vas a olvidar en un momento crítico. O ese conjunto de operaciones supuestamente de solo lectura de repente no lo es, ya sea porque un programador posterior no se dio cuenta de que se suponía que era o porque su código llama a una función que tiene una escritura oculta. Por ejemplo, configuro mis clientes de base de datos de línea de comandos para que no se comprometan automáticamente. Esto significa que puedo hacer un dedo gordo en una consulta de eliminación y aún revertir.

Existe el nivel de aislamiento, como se señaló. Esto le permite hacer varias lecturas sin preocuparse si algún otro proceso ha escrito en sus datos entre ellos, haciendo sus lecturas efectivamente atómicas. Esto te ahorrará muchas horas depurando una condición de carrera.

Y, finalmente, a menudo puede configurar una transacción para que sea de solo lectura. Esto verifica su suposición y generará un error si algo intenta escribir.

Aquí hay un buen artículo que lo resume todo . Los detalles son específicos de Oracle, pero los conceptos son genéricos.

Las transacciones son necesarias para operaciones de solo lectura si desea establecer un tiempo de espera específico para consultas que no sean el tiempo de espera predeterminado, o si desea cambiar el nivel de aislamiento.

Además, cada base de datos, no sé acerca de las excepciones, iniciará internamente una transacción para cada consulta. En general, se considera que no se ha realizado para deshacer transacciones cuando no se requiere dicha reversión.

Los DBA pueden estar monitoreando la actividad de reversión, y cualquier comportamiento de reversión predeterminado los molestará en ese caso.

Por lo tanto, las transacciones se utilizan de todos modos, ya sea que las inicie o no. Si no los necesita, no los inicie, pero nunca retroceda en operaciones de solo lectura.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top