registro obtener fecha anterior mysql transactions locking

mysql - obtener - registro anterior oracle



Comportamiento de MySQL ''seleccionar para actualizar'' (1)

Déjame revisar tus casos y explicar cómo funcionan estos bloqueos:

1 caso

T1 quiere actualizar algunas filas en su tabla de prueba. Esta transacción pone el bloqueo IX en todas las tablas y el bloqueo X en las primeras 5 filas.

T2 quiere actualizar algunas filas en su tabla de prueba. Esta transacción pone el bloqueo IX (porque IX es compatible con IX) en todas las tablas e intenta las primeras 5 filas pero no puede hacerlo porque X no es compatible con X

Así que estamos bien.

2.1 caso

T1 quiere actualizar algunas filas en su tabla de prueba. Esta transacción puso el bloqueo IX en todas las tablas y el bloqueo X en las primeras 5 filas.

T2 quiere seleccionar algunas filas de su tabla de prueba. Y no coloca ningún bloqueo (porque InnoDB proporciona lecturas sin bloqueo)

2.1 caso

T1 quiere actualizar algunas filas en su tabla de prueba. Esta transacción puso el bloqueo IX en todas las tablas y el bloqueo X en las primeras 5 filas.

T2 desea actualizar (seleccionar para actualizar) algunas filas de su tabla de prueba. Coloque IS en toda la tabla e intenta obtener un bloqueo de S en la fila y falla porque X y S no son compatibles.

Además, siempre tenga en cuenta el nivel de aislamiento: los diferentes niveles causan diferentes mecanismos para liberar / adquirir bloqueos

Espero eso ayude

Según la documentación de MySql, MySql admite el bloqueo de granularidad múltiple (MGL).

caso 1

Terminal abierta 1:

// conectado a mysql

mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select id, status from tracking_number limit 5 for update; +----+--------+ | id | status | +----+--------+ | 1 | 0 | | 2 | 0 | | 3 | 0 | | 4 | 0 | | 5 | 0 | +----+--------+ 5 rows in set (0.00 sec) mysql>

Dejó abierto y abrió la terminal-2:

// conectado a mysql

mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select id, status from tracking_number limit 5 for update; <!-- Hangs here. and after some time it says--> ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

Aunque hay muchas filas para recuperar, T2 espera hasta que t1 se completa.

caso-2

Terminal 1 izquierdo como está. Ahora en terminal 2:

mysql> start transaction; Query OK, 0 rows affected (0.00 sec) <!-- case 2.1 --> mysql> select id, status from tracking_number where id=1; +----+--------+ | id | status | +----+--------+ | 1 | 0 | +----+--------+ 1 row in set (0.00 sec) mysql> select id, status from tracking_number where id=2; +----+--------+ | id | status | +----+--------+ | 2 | 0 | +----+--------+ 1 row in set (0.00 sec) <!-- case 2.2 --> mysql> select * from tracking_number where id=2 for update; <!-- Hangs here. and after some time --> ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

  1. Pero ¿por qué en el caso 1, T2 espera el mismo conjunto de filas que T1 ha bloqueado?

  2. ¿Significa que la consulta de selección ilimitada (incluso con el parámetro limint. También he intentado con un rango diferente) bloquea toda la tabla?

  3. ¿Hay alguna manera de permitir que las transacciones se bloqueen de forma independiente sin especificar el campo del registro (es decir, sin usar donde campo = valor )?
  4. Generalmente (o según el bloqueo concurrente de Java), el bloqueo de escritura es exclusivo y la lectura no lo es. En el caso 2.1, aunque los registros están en modo de bloqueo de escritura, ¿cómo T2 puede leer los mismos registros? Dado que esto está permitido, ¿cuál es el punto de bloquearlo?
  5. Se entiende el caso 2.2.

Abrió un terminal y una transacción:

mysql> update tracking_number set status=4 where status=0 limit 5; Query OK, 5 rows affected (0.00 sec) Rows matched: 5 Changed: 5 Warnings: 0

Lo dejé allí y abrí otro terminal y transacción:

mysql> update tracking_number set status=5 where status=0 limit 5;

T2 no tuvo éxito hasta que confirmé (o deshacer) T1.

  1. ¿Por qué es este comportamiento?