¿Cuál es el efecto de tener una transacción abierta en MSSQL durante demasiado tiempo?

11

Me pregunto qué sucede si comienza una transacción en una base de datos y se olvida de confirmarla o deshacerla. ¿El servidor estará inactivo? Digamos que lo dejaste por 3 días.

También hay usuarios que lo están utilizando asumiendo que los otros usuarios no sabían que hay una transacción no cerrada (supongamos que los usuarios solo están insertando datos en la base de datos). ¿Cuáles son las consecuencias de esta acción?

JanLeeYu
fuente

Respuestas:

14

Tener una transacción abierta por sí solo casi no tendrá consecuencias. Un simple

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

en el peor de los casos, tendrá algunos bytes de valores de estado. No es gran cosa.

La mayoría de los programas harán un trabajo real dentro de la transacción y este es otro asunto. El objetivo de una transacción es que puede estar seguro de que varios hechos dentro de la base de datos son verdaderos simultáneamente, a pesar de que hay otros usuarios que escriben en la misma base de datos al mismo tiempo.

Tome el ejemplo canónico de transferir dinero entre cuentas bancarias. El sistema debe garantizar que la cuenta de origen exista, que tenga fondos suficientes, que exista la cuenta de destino y que ocurra el débito y el crédito o que ninguno ocurra. Debe garantizar esto mientras ocurren otras transacciones, tal vez incluso entre estas dos cuentas. El sistema asegura esto mediante bloqueos en las mesas en cuestión. El nivel de aislamiento de las transacciones controla qué bloqueos se toman y qué parte del trabajo de otras personas se ve .

Entonces, si hace mucho trabajo, existe una buena posibilidad de que otras transacciones se pongan en cola esperando los objetos en los que mantiene bloqueos. Esto reducirá el rendimiento general del sistema. Eventualmente alcanzarán los límites de tiempo de espera y fallarán, lo cual es un problema para el comportamiento general del sistema. Si usa un nivel de aislamiento optimista, su transacción puede fallar cuando intenta una confirmación debido al trabajo de otros.

Mantener bloqueos requiere recursos del sistema. Esta es la memoria que el sistema no puede usar para procesar otras solicitudes, lo que reduce el rendimiento.

Si se ha realizado mucho trabajo, el sistema puede optar por realizar la escalada de bloqueo . En lugar de bloquear filas individuales, se bloqueará toda la tabla. Entonces, más usuarios concurrentes se verán afectados, el rendimiento del sistema disminuirá aún más y el impacto de la aplicación será mayor.

Los cambios de datos se escriben en el archivo de registro, al igual que los bloqueos que los protegen. No se pueden borrar del registro hasta que se confirme la transacción. Por lo tanto, una transacción muy larga puede causar la hinchazón del archivo de registro con sus problemas asociados.

Si el trabajo actual usa tempdb, que es probable para grandes cargas de trabajo, los recursos allí pueden estar atados hasta el final de la transacción. En casos extremos, esto puede hacer que otras tareas fallen porque ya no hay suficiente espacio para ellas. He tenido casos en los que una ACTUALIZACIÓN mal codificada llenó tempdb por lo que no quedaba suficiente disco para la CLASIFICACIÓN de un informe y el informe falló.

Si elige ROLLBACK la transacción, o el sistema falla y se recupera, el tiempo necesario para que el sistema vuelva a estar disponible dependerá de la cantidad de trabajo realizado. Simplemente tener una transacción abierta no afectará el tiempo de recuperación, es la cantidad de trabajo realizado. Si la transacción estuvo abierta pero inactiva durante una hora, la recuperación será casi instantánea. Si estaba escribiendo constantemente durante esa hora, la regla general es que el tiempo de recuperación también será de aproximadamente una hora.

Como puede ver, las transacciones largas pueden ser problemáticas. Para los sistemas OLTP, la mejor práctica es tener una transacción de base de datos por transacción comercial. Para entrada de proceso de trabajo por lotes en bloques, con confirmaciones frecuentes, y reinicio lógico codificado. Por lo general, se pueden procesar varios miles de registros dentro de una sola transacción de base de datos, pero se debe probar la concurrencia y reabsorber el consumo.

No se sienta tentado a ir al otro extremo y evite las transacciones y bloqueos por completo. Si necesita mantener la coherencia dentro de sus datos (¿y por qué usaría una base de datos?), Los niveles de aislamiento y las transacciones tienen un propósito muy importante. Conozca sus opciones y decida con qué equilibrio de concurrencia y corrección está preparado para vivir para cada parte de su solicitud.

Michael Green
fuente
incluso si está abierto por tres días?
JanLeeYu
Sí, incluso por tres días. El punto importante es la cantidad de trabajo que se ha realizado mientras el TX está abierto, no solo por cuánto tiempo ha estado abierto. Por supuesto, como DBA, es posible que desee preguntar al propietario de la transacción por qué necesitan que esté abierto durante tanto tiempo. Cuando dirigí un equipo de DBA, registré todo el TX que había estado abierto durante más de 30 minutos y tuve una conversación con el propietario.
Michael Green
OKAY. Gracias por la grandiosa explicación. Aunque todos también lo hicieron genial.
JanLeeYu
Qué alivio ... Gracias de nuevo por la respuesta.
JanLeeYu
"ACTUALIZACIÓN mal codificada" Sí. Visto esto. Una declaración de actualización dentro de un bucle que no calificó algunos nombres y resultó en un comportamiento similar a 1 = 1, por lo que actualizó toda la tabla para cada iteración del bucle (que también puso los datos incorrectos en la mayoría de esas filas).
jpmc26
6

Su mayor consecuencia será el bloqueo de los objetos utilizados en la transacción. Especialmente si asume que sus usuarios están insertando datos, entonces esa transacción de larga duración podría incluir sentencias SELECT en tablas de uso común. Es posible que las declaraciones de actualización de sus usuarios no puedan obtener el bloqueo necesario para completar sus actualizaciones o inserciones.

Una cosa secundaria que podría suceder es la actividad del archivo de registro, por ejemplo, si estaba actualizando un conjunto de datos grande, la parte del registro que está utilizando la transacción se mantiene activa durante la duración de esa transacción. No podrá reutilizar esa parte del registro hasta que la transacción se confirme o se revierta. En escenarios en los que puede estar en un sistema OLTP muy activo, esto podría hacer que su archivo de registro crezca rápidamente, llenando su dispositivo de almacenamiento.

Andriy M
fuente
por ejemplo, el que creó la transacción está desconectado del servidor, ¿podrá volver a iniciar sesión en el servidor para cerrar la transacción?
JanLeeYu
Dependerá de que, si la transacción se realizó en un entorno que utilizó MSDTC, podría ser una transacción huérfana. En ese caso, el usuario ya no podrá cerrarlo por sí mismo ... el DBA tendrá que intervenir para manejarlo. Fuera de eso, generalmente debería ver que SQL Server cancela la transacción cuando se desconecta ... pero nuevamente en transacciones grandes que pueden no ser el caso cada vez.
En caso de que eso suceda, ¿el administrador aún podrá cerrar la transacción correctamente?
JanLeeYu
No puedo responder a eso, todo depende. He tenido casos en los que el servidor tuvo que reiniciarse o la instancia falló al nodo / réplica secundario.
4

La transacción incompleta puede contener una gran cantidad de bloqueos y causar bloqueo

Cuando una transacción no se completa ya sea porque se agota el tiempo de espera de una consulta o porque el lote se cancela en medio de una transacción sin emitir una instrucción COMMIT o ROLLBACK para completar la transacción, la transacción se deja abierta y todos los bloqueos adquiridos durante esa transacción continúan ser agarrado. Las transacciones posteriores ejecutadas bajo la misma conexión se tratan como transacciones anidadas, por lo que no se liberan todos los bloqueos adquiridos en estas transacciones completadas. Este problema se repite con todas las transacciones ejecutadas desde la misma conexión hasta que se ejecuta un ROLLBACK. Como resultado, se retiene una gran cantidad de bloqueos, se bloquean los usuarios y se pierden las transacciones, lo que da como resultado datos que son diferentes de lo que espera.

fuente

Pimp Juice IT
fuente
por ejemplo, el que creó la transacción está desconectado del servidor, ¿podrá volver a iniciar sesión en el servidor para cerrar la transacción?
JanLeeYu
Una vez que SQL Server sepa que se ha perdido la conexión, revertirá la transacción. Ver aquí dba.stackexchange.com/questions/47404/… . Si el mismo usuario se vuelve a conectar, será una sesión diferente, por lo que de alguna manera no puede "adoptar" la transacción anterior.
Michael Green