2011-07-07 11 views
16

He leído this article from dev.mysql.SELECCIONAR BLOQUEO EN EL MODO COMPARTIR

en esa página es un ejemplo de que cuando el uso de seleccionar para la actualización y el no uso de bloqueo en el modo de acción y dice

Aquí, LOCK IN SHARE MODE no es una buena solución porque si dos usuarios leen el contador al mismo tiempo, al menos uno de ellos termina en punto muerto cuando entra en intentos para actualizar el contador

pero primera línea de esta página dice

SELECT ... LOCK IN SHARE MODE: Los filas de lectura son los últimos disponibles, por lo que ** si pertenecen a otra transacción ** que no ha aún comprometido, lee bloques hasta que la transacción finalice.

¿hay una paradoja?

me refiero a dos usuarios no leen el contador al mismo tiempo beacause si pertenecen a otra transacción los bloques de lectura hasta que finalice la transacción.

Respuesta

18

Si hay otra transacción, que ha modificado la fila, el SELECCIONAR ... BLOQUEO EN MODO COMPARTIR espera. Si la fila no se modifica, no espera. Lo que lleva a la primera situación, esa transacción 2 puede SELECCIONAR ... BLOQUEAR EN MODO COMPARTIR, pero ninguno de ellos puede actualizar el registro (interbloqueo)

+0

así que seleccione para la actualización espere si la fila bloqueada fue modificada o no modificada por el usuario1 antes de confirmar y bloquear en el modo compartir ¿solo espera si el usuario1 modifica la fila bloqueada antes de la confirmación? – user677900

+4

la diferencia es que puede seleccionar el mismo registro en 2 transacciones con seleccionar ... bloquear en modo compartir, pero no puede con seleccionar ... para actualizar. seleccione para la actualización bloquea otra seleccione para actualizar o seleccione bloqueo en modo compartir en el mismo registro. –

11

Pruebe esto. Abra dos terminales, p. PowerShell en Windows, xterm, la consola de Linux, .... conecte a MySQL:

crear child_codes mesa (tomado de MySQL documentation)

mysql> create table child_codes (counter_field integer); 
Query OK, 0 rows affected (0.05 sec) 

mysql> insert into child_codes set counter_field = 1; 
Query OK, 1 row affected (0.00 sec) 

session 1 (terminal 1):    session 2 (terminal 2):                   

              mysql> start transaction; 
              Query OK, 0 rows affected (0.00 sec) 

              mysql> select counter_field from child_codes 
                 lock in share mode; 
              +---------------+ 
              | counter_field | 
              +---------------+ 
              |    1 | 
              +---------------+ 
              1 row in set (0.00 sec) 

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 
mysql> select counter_field from 
      child_codes lock in share mode; 
+---------------+ 
| counter_field | 
+---------------+ 
|    1 | 
+---------------+ 

              mysql> update child_codes set counter_field = 2; 
              ERROR 1205 (HY000): Lock wait timeout exceeded; 
              try restarting transaction 

yo también pensé que si otra transacción ejecuta consulta de selección de bloqueo de la cuota modo esta consulta está bloqueada (a la espera de que se confirmen o reviertan otras transacciones). Pero como Darhazer mencionó Si la fila no se modifica, no espera. Creo que este comportamiento debe mencionarse en la documentación de MySQL.

+0

El ejemplo parece poco práctico y contradice con "* Otras sesiones pueden leer las filas, pero no pueden modificarlas hasta que la transacción se comprometa. Si alguna de estas filas fue modificada por otra transacción que aún no se ha confirmado, su consulta esperará hasta que la transacción finaliza y luego usa los últimos valores. * "No se debe detectar ningún bloqueo o interbloqueo, si otra transacción liberó el bloqueo. http://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html – Tiny

Cuestiones relacionadas