transaction transacción repeatable read_uncommitted read pudo obtener niveles lectura instantánea ejemplos datos confirmada begin aislamiento acceso sql database database-design transactions

sql - repeatable - ¿Cuál es el mejor nivel de aislamiento de transacción predeterminado para un ERP, si corresponde?



repeatable read (5)

Breve reseña: Estamos empezando a migrar / reimplementar un sistema ERP a Java con Hibernate, teniendo como objetivo un conteo de usuarios simultáneos de 50-100 usuarios que usan el sistema. Usamos MS SQL Server como servidor de base de datos, que es lo suficientemente bueno para estas cargas.

Ahora, el sistema anterior no usa ninguna transacción y depende de partes críticas (por ejemplo, cambios en las existencias) al configurar bloqueos manuales (usando indicadores) y soltarlos. Eso es algo así como la gestión manual de transacciones. Pero a veces hay problemas con la inconsistencia de los datos. En el nuevo sistema, nos gustaría utilizar las transacciones para eliminar estos problemas.

Ahora la pregunta: ¿Cuál sería un nivel de aislamiento de transacción predeterminado bueno / razonable para usar en un sistema ERP, dado un uso de aproximadamente 85% de OLTP y 15% de OLAP? ¿O debería decidir siempre por tarea, qué nivel de transacción usar?

Y como recordatorio de los cuatro niveles de aislamiento de transacciones: LEER SIN COMPROMISO, LEER COMPROMETIDOS, REPETIR LEER, SERIALIZABLE


Depende mucho de la forma en que diseñe su aplicación, la respuesta fácil solo se ejecuta en READ_COMMITTED.

Puede argumentar que si diseña su sistema teniendo en cuenta que podría usar READ_UNCOMMITTED como predeterminado y solo aumentar el nivel de aislamiento cuando lo necesite. La gran mayoría de sus transacciones van a tener éxito de todos modos, por lo que leer datos no confirmados no será un gran problema.

La forma en que los niveles de aislamiento afectan sus consultas depende de su base de datos de destino. Por ejemplo, las bases de datos como Sybase y MSSQL deben bloquear más recursos cuando ejecuta READ_COMMITTED, que las bases de datos como Oracle.


No te olvides de SNAPSHOT, que está justo debajo de SERIALIZABLE.

Depende de cuán importante es que los datos sean precisos en los informes. Realmente es una tarea por tarea.


Para SQL Server (y probablemente la mayoría de los RDBMS principales), me quedaría con el predeterminado. Para SQL Server, esto es LEÍDO COMPROMETIDO. Algo más y empiezas a sobrecargar el DB, cualquier cosa menos y tienes problemas de consistencia.


99 veces de cada 100, leer comprometido es la respuesta correcta. Eso asegura que solo vea los cambios que ha cometido la otra sesión (y, por lo tanto, los resultados que son consistentes, suponiendo que haya diseñado sus transacciones correctamente). Pero no impone la sobrecarga de bloqueo (particularmente en bases de datos que no son de Oracle) que la lectura repetible o la imposición serializable.

Muy ocasionalmente, es posible que desee ejecutar un informe en el que esté dispuesto a sacrificar la precisión de la velocidad y establecer un nivel de aislamiento de lectura no comprometida. Rara vez es una buena idea, pero ocasionalmente es una solución razonablemente aceptable para bloquear problemas de contención.

La lectura serializable y repetible se usa ocasionalmente cuando se tiene un proceso que necesita ver un conjunto coherente de datos durante toda la ejecución, independientemente de lo que estén haciendo otras transacciones en ese momento. Puede ser apropiado establecer un proceso de reconciliación de fin de mes para ser serializable, por ejemplo, si hay un montón de código de procedimiento, una posibilidad de que los usuarios vayan a hacer cambios mientras el proceso se está ejecutando y un requisito que el proceso necesita para asegúrese de que siempre vea los datos tal como estaban en el momento en que comenzó la reconciliación.


Leer No comprometido es definitivamente el menos favorecido en la mayoría de los foros. Sin embargo, hay razones para usarlo que van más allá de una cuestión de "velocidad versus precisión" que a menudo se señala.

Digamos que tienes:

  • Transacción T1: escribe B, lee A, (algo más de trabajo), confirma.
  • Transacción T2: escribe A, lee B, (algo más de trabajo), confirma.

Si se confirma la lectura, las transacciones anteriores no se liberarán hasta la confirmación. Entonces puede encontrarse con una situación en la que T1 está esperando que T2 libere A, y T2 está esperando que T1 libere B. Aquí las dos transacciones colisionan en un bloqueo.

Puede volver a escribir esos procedimientos para evitar este escenario (ejemplo: ¡adquiera recursos siempre en orden alfabético!). Aún así, con demasiados usuarios concurrentes y decenas de miles de líneas de código, este problema puede ser muy probable y muy difícil de diagnosticar y resolver.

La alternativa es usar Read Uncommitted. Luego, diseña sus transacciones asumiendo que puede haber lecturas sucias. Personalmente encuentro este problema mucho más localizado y tratable que los trenes de guerra entrelazados.

Los problemas de las lecturas sucias pueden ser reemplazados por

  • (1) Retrocesos: no. Esta debería ser la última línea de defensa en caso de falla del hardware, falla de la red o falla del programa solamente.

  • (2) Use bloqueos de aplicaciones para crear un mecanismo de bloqueo que opere en un nivel más alto de abstracción, donde cada bloqueo esté más cerca de un recurso o acción real.