Hm, vamos a enumerar todos los casos.
REQUIRES_NEW
no anida realmente las transacciones, pero como mencionas hace una pausa en la actual. Entonces, simplemente hay dos transacciones que acceden a la misma información. (Esto es similar a dos transacciones concurrentes regulares, excepto que no son concurrentes, sino en el mismo hilo de ejecución).
T1 T2 T1 T2
― ―
| |
|
― | ―
| | |
| = | |
― | ―
|
| |
― ―
entonces tenemos que considerar optimista vs pesimista bloqueo.
Además, tenemos que considerar vaciados operados por ORMs. Con los ORM, no tenemos un control claro cuando se producen escrituras, ya que flush
está controlado por el marco. Por lo general, un color implícito ocurre antes de la confirmación, pero si se modifican muchas entradas, el marco también puede hacer descargas intermedias.
1) Consideremos el bloqueo optimista, donde leer no adquiere bloqueos, pero escribir adquiere bloqueos exclusivos.
La lectura por T1 no adquiere un bloqueo.
1a) Si T1 sí enjuagó los cambios prematuramente, adquirió un bloqueo exclusivo. Cuando T2 se compromete, intenta adquirir el bloqueo pero no puede. El sistema está bloqueado. Esto puede ser un tipo de punto muerto en particular. La finalización depende de cómo transcurran las transacciones o bloqueos.
1b) Si T1 no eliminó los cambios prematuramente, no se ha adquirido ningún bloqueo. Cuando T2 se compromete, lo adquiere y lo libera y es exitoso. Cuando T1 intenta comprometerse, nota un conflicto y falla.
2) Consideremos el bloqueo pesimista, donde leer adquiere bloqueos compartidos y escribe bloqueos exclusivos.
La lectura por T1 adquiere un bloqueo compartido.
2a) Si T1 se enjuaga prematuramente, se convierte en una cerradura exclusiva. La situación es similar a 1a)
2b) Si T1 no se descargó prematuramente, T1 tiene un bloqueo compartido. Cuando T2 se compromete, intenta adquirir un bloqueo y bloques exclusivos. El sistema está bloqueado de nuevo.
Conclusión: está bien con un bloqueo optimista si no ocurre un lavado prematuro, que no se puede controlar estrictamente.
¿Cómo y dónde se produce un punto muerto? ¿Desde el caché de la sesión o desde las filas bloqueadas de la base de datos? –