2009-05-03 16 views
40

Parece haber opiniones muy diferentes sobre el uso de transacciones para leer desde una base de datos.¿Transacciones para acceso DB de solo lectura?

Presupuesto de la DeveloperWorks artículo Transaction strategies: Models and strategies overview:

¿Por qué necesitaría una transacción si solo leyendo los datos? La respuesta es que no. Inicio de una transacción para realizar una lectura única operación se suma a los gastos generales de la rosca procesamiento y puede causar compartida bloqueos de lectura en la base de datos (dependiendo de qué tipo de base de datos que está utilizando y lo que el nivel de aislamiento se establece a).

Como opinión contraria no es la siguiente cita de la documentación de Hibernate Non-transactional data access and the auto-commit mode

Nuestra recomendación es no utilizar el modo confirmación automática en una aplicación, y aplicar sólo lectura sólo cuando las transacciones hay un beneficio obvio de rendimiento o cuando los cambios futuros del código son altamente improbables. Siempre prefiera transacciones ACID regulares al grupo sus operaciones de acceso a datos, independientemente de si lee o escribe datos.

También hay un debate similar en la lista de correo de EclipseLink here.

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

Por lo que puedo ver, solo hace la diferencia si el nivel de aislamiento es más alto que "leer confirmado". ¿Es esto correcto?

¿Cuáles son las experiencias y recomendaciones?

Respuesta

16

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

  • establecer tiempos de espera o modos de bloqueo
  • Conjunto nivel de aislamiento

estándar SQL requiere que incluso una consulta debe iniciar una nueva transacción si no hay ninguna transacción actualmente en progreso. Hay DBMS donde eso no es lo que sucede, por ejemplo, aquellos con un modo de confirmación automática (la instrucción inicia una transacción y la compromete inmediatamente después de que la declaración finalice). Otros DBMS realizan sentencias atómicas (confirmación automática efectiva) de forma predeterminada, pero inician una transacción explícita con una instrucción como 'COMENZAR TRABAJO', cancelando el compromiso automático hasta el próximo COMMIT o ROLLBACK (IBM Informix Dynamic Server es uno de esos, cuando la base de datos no es MODE ANSI).

No estoy seguro acerca del consejo de nunca retroceder. No hace ninguna diferencia en la transacción de solo lectura, y en la medida en que molesta a tus DBA, entonces es mejor evitar ROLLBACK. Pero si su programa finaliza sin realizar un COMMIT, el DBMS debería hacer un ROLLBACK en su transacción incompleta, sin duda si modificó la base de datos y (por simplicidad) incluso si solo seleccionó datos.

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

8

Se requieren transacciones 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, que desconoce las excepciones, iniciará internamente una transacción para cada consulta. En general, se considera que no se realiza una reversión de transacciones cuando esa reversión no es necesaria.

Los DBA pueden estar supervisando la actividad de retrotracción, y cualquier comportamiento de retrotracció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 realice una reversión en las operaciones de solo lectura.

8

En primer lugar, esto suena como una optimización prematura. Como Steven señaló, las bases de datos más sensatas te pondrán en una transacción de todos modos, y lo único que están haciendo es llamar a commit después de cada declaración. Entonces, desde esa perspectiva, el compromiso automático puede ser menos eficaz ya que cada enunciado debe comenzar una nueva transacción. O tal vez no. Solo el benchmarking lo dirá y apuesto a que no hace lamer la diferencia en su aplicación.

Una razón por la que desea utilizar siempre una transacción es la consistencia de la protección. Si empiezas a jugar manualmente declarando una transacción solo cuando "necesitas", entonces te olvidarás 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 bases de datos de línea de comandos para que no se confirmen automáticamente. Esto significa que puedo presionar con el dedo una consulta de eliminación y seguir retrocediendo.

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 que sus lecturas sean efectivamente atómicas. Esto te ahorrará muchas horas depurando una condición de carrera.

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

Here's a nice article summing it all up. Los detalles son específicos de Oracle, pero los conceptos son genéricos.

Cuestiones relacionadas