INSERT: selecciona y pone al día en condiciones de carrera

votos
0

# 1: Si me quedo

INSERT INTO foo SELECT MAX(X) FROM bar;

¿Puedo estar seguro de que acaba de insertar el valor máximo de la Xcolumna de la barmesa? Que ninguna otra sesión logró manipular la barmesa después de la SELECTse completó parte, pero antes de que el INSERTse terminó?

# 2: Si me quedo

UPDATE foo SET x = 0 WHERE y = 100;

cuando un reloj marque las 00:00 y la consulta tarda 2 minutos, puedo estar seguro de que todas las filas que tenían y = 100a las 00:00 se ha actualizado? Que ninguna otra sesión logró cambiar y = 100a y = 80antes de mi consulta terminado?

# 3: Esto está relacionado con # 2. Si a las 00:01 otra sesión hace una UPDATEs a una fila cambiando y = 99a y = 100, qué mi consulta anterior tratan de UPDATEesta fila?

Publicado el 07/11/2018 a las 22:51
fuente por usuario
En otros idiomas...                            


2 respuestas

votos
1

Si usted no utiliza transacciones explícitas, cada consulta se trata como una transacción por sí mismo. Así que una consulta que combina INSERTy SELECTal igual que su # 1 puede depender de la consistencia. Es más o menos equivalente a:

START TRANSACTION;
SET @max = (SELECT MAX(x) FROM bar);
INSERT INTO foo VALUES (@max);
COMMIT;

Sin embargo, las transacciones no hacen una instantánea de toda la base de datos en el momento se inicia la transacción. InnoDB emplea bloqueo por registro. Así que en el # 2 y # 3, si usted tiene una sesión de puesta al día y, mientras que la sesión B realizar la consulta a mostrar, los registros que las actualizaciones B pueden o no incluir los modificados por A, según el orden relativo de estos cambios específicos. MyISAM, por el contrario, utiliza bloqueos a nivel de tabla, por lo que esto no debería ser posible; lo que consulta inicia por primera vez, se bloqueará la foomesa, y la otra consulta esperará a que termine antes de que comience la exploración de la tabla.

Respondida el 14/11/2018 a las 21:22
fuente por usuario

votos
0

Las transacciones se utilizan para garantizar el estado de la base de datos. La lectura repetible así que cuando lea el valor máximo que puede leer una y otra vez que seguirá siendo el mismo.

https://dev.mysql.com/doc/refman/5.6/en/innodb-transaction-isolation-levels.html#isolevel_repeatable-read

A continuación, se establece la transacción

https://dev.mysql.com/doc/refman/5.6/en/set-transaction.html

A continuación, la actualización de su código de x = (select max (y) desde z)

después de confirmar la transacción

Que podría haber perdido algo, pero en general, que es como se hace para los informes preceise.

Respondida el 07/11/2018 a las 23:26
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more