¿Es una mala práctica crear siempre una transacción?
Por ejemplo, ¿es una buena práctica crear una transacción para nada más que una simple SELECT
?
¿Cuál es el costo de crear una transacción cuando no es realmente necesario?
Incluso si está utilizando un nivel de aislamiento como READ UNCOMMITTED
, ¿es una mala práctica?
BEGIN TRAN SELECT ... COMMIT
vs soloSELECT
allí parece ser una diferencia de rendimiento extremadamente menor .Respuestas:
¿Es una mala práctica crear una transacción siempre?
Depende de qué contexto estás hablando aquí. Si se trata de una actualización, recomiendo utilizar TRANSACTIONS explícitamente. Si es un SELECT, entonces NO (explícitamente).
Pero espere, hay más para entender primero: todo en el servidor SQL está contenido en una transacción.
Cuando la opción de sesión
IMPLICIT_TRANSACTIONS
esOFF
y se especifica de forma explícitabegin tran
ycommit/rollback
entonces esto se conoce comúnmente como una transacción explícita . De lo contrario, obtendrá una transacción de confirmación automática.Cuándo
IMPLICIT_TRANSACTIONS
esON
una transacción implícita se inicia automáticamente al ejecutar uno de los tipos de instrucciones documentados en el artículo en línea de los libros (por ejemplo,SELECT
/UPDATE
/CREATE
) y debe confirmarse o revertirse explícitamente. La ejecución de aBEGIN TRAN
en este modo aumentaría@@TRANCOUNT
e iniciaría otra transacción "anidada")Para cambiar en qué modo estás, usarías
o
si lo anterior devuelve 2, está en modo de transacción implícita. Si devuelve 0, está en confirmación automática.
¿Cuánto es el costo de crear una transacción cuando no es realmente necesario?
Se necesitan transacciones para llevar la base de datos de un estado consistente a otro estado consistente. Las transacciones no tienen costo ya que no hay alternativa a las transacciones. Consulte: Uso de niveles de aislamiento basados en versiones de fila
Incluso si está utilizando un nivel de aislamiento read_uncomitted. ¿Es una mala práctica? porque no debería tener problemas con el bloqueo.
El nivel de aislamiento READ_UNCOMMITED permitirá lecturas sucias por definición, es decir, una transacción podrá ver los cambios no confirmados realizados por otra transacción. Lo que hace este nivel de aislamiento es que relaja la sobrecarga del bloqueo: método de adquirir bloqueos para proteger la concurrencia de la base de datos.
Puede usar esto en un nivel de conexión / consulta, para que no afecte otras consultas.
Encontré un artículo interesante de Jeff Atwood que describe Deadlocks debido al Rompecabezas de Dining Philosophers y describe el nivel de aislamiento de instantáneas de lectura comprometida .
EDITAR:
Por curiosidad, hice algunas pruebas para medir el impacto en T-log con contadores de Perfmon como Log Bytes Flushed / Sec, Log Flush Waits / Sec (Número de confirmaciones por segundo que esperan que ocurra LOG flush) como se muestra en el siguiente gráfico:
Código de muestra :
Transacciones de confirmación automática : (Editado como resaltado por @TravisGan)
IMPLÍCITA y transacción explícita:
Hay un DMV sys.dm_tran_database_transactions que devolverá información sobre las transacciones a nivel de base de datos.
Obviamente, esta es una especie de prueba simplista para mostrar el impacto. También influirán otros factores como el subsistema de disco, la configuración de crecimiento automático de la base de datos, el tamaño inicial de la base de datos, otros procesos que se ejecutan en el mismo servidor \ base de datos, etc.
De las pruebas anteriores, no hay casi ninguna diferencia entre las transacciones implícitas y explícitas.
Gracias a @TravisGan por ayudar a agregar más a la respuesta.
fuente
Una instrucción SQL siempre se ejecuta en una transacción. Si no inicia una explícitamente, cada instrucción SQL se ejecutará en una transacción de sí misma.
La única opción es si agrupa múltiples declaraciones en una transacción. Las transacciones que abarcan varias declaraciones dejan bloqueos que perjudican la concurrencia. Entonces, "siempre" crear una transacción no es una buena idea. Debe equilibrar el costo con el beneficio.
fuente
El problema es si un grupo de operaciones debe tratarse como una sola acción. En otras palabras, todas las operaciones deben completarse y confirmarse con éxito o ninguna de las operaciones puede confirmarse. Si tiene un escenario que requiere que lea datos preliminares y luego realice actualizaciones basadas en esos datos, entonces la lectura inicial probablemente debería ser parte de la transacción. Nota: Estoy evitando Seleccionar / Insertar / Actualizar a propósito. El alcance de la transacción puede estar realmente en el nivel de la aplicación e involucrar múltiples operaciones de bases de datos. Piense en patrones clásicos como Reserva de asiento de avión o Consulta / retirada de saldo bancario. Se debe tener una visión más amplia del problema para garantizar que toda la aplicación produzca datos confiables y consistentes.
fuente