En ciertas circunstancias, no es conveniente una lectura
        consistente. Por ejemplo, se podría desear agregar una fila en
        la tabla hijo, y estar seguro de que dicha
        fila tiene una fila padre en la tabla padre.
        El siguiente ejemplo muestra cómo implementar integridad
        referencial en el código de la aplicación.
      
        Suponiendo que se utiliza una lectura consistente para leer la
        tabla padre y efectivamente puede verse el
        registro padre para la fila hijo que se agregará, ¿puede
        agregarse en forma segura la fila hijo dentro de la tabla
        hijo? No, porque puede haber ocurrido que
        entretanto otro usuario haya borrado el registro padre de la
        tabla padre, sin que se tenga conocimiento de
        ello.
      
        La solución es llevar a cabo el SELECT en un
        modo con bloqueo, utilizando LOCK IN SHARE
        MODE:
      
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;
        Realizar una lectura en modo compartido (share mode) significa
        que se leen los últimos datos disponibles, y se establece un
        bloqueo en modo compartido en los registros que se leen. Un
        bloqueo en modo compartido evita que otros actualicen o eliminen
        la fila que se ha leido. Además, si los datos más actualizados
        pertenecen a una transacción todavía no confirmada de otra
        conexión, se espera hasta que la transacción se confirme.
        Luego de ver que la mencionada consulta devuelve el registro
        padre 'Jones', se puede agregar con seguridad
        el registro hijo en la tabla hijo y confirmar
        la transacción.
      
        Otro ejemplo: se tiene un campo contador, entero, en una tabla
        llamada child_codes que se emplea para
        asignar un identificador único a cada registro hijo agregado a
        la tabla hijo. Obviamente, utilizar una
        lectura consistente o una lectura en modo compartido para leer
        el valor actual del contador no es una buena idea, puesto que
        dos usuarios de la base de datos pueden ver el mismo valor del
        contador, y agregar registros hijos con el mismo identificador,
        lo cual generaría un error de clave duplicada.
      
        En este caso, LOCK IN SHARE MODE no es una
        buena solución porque si dos usuarios leen el contador al mismo
        tiempo, al menos uno terminará en un deadlock cuando intente
        actualizar el contador.
      
        En este caso, hay dos buenas formas de implementar la lectura e
        incremento del contador: (1), actualizar el contador en un
        incremento de 1 y sólo después leerlo, o (2) leer primero el
        contador estableciendo un bloqueo FOR UPDATE,
        e incrementándolo luego. La última puede ser implementada como
        sigue:
      
SELECT counter_field FROM child_codes FOR UPDATE; UPDATE child_codes SET counter_field = counter_field + 1;
        Una sentencia SELECT ... FOR UPDATE lee el
        dato más actualizado disponible, estableciendo bloqueos
        exclusivos sobre cada fila leída. Es decir, el mismo bloqueo
        que haría UPDATE.
      
        Nótese que el anterior es un sencillo ejemplo de cómo funciona
        SELECT ... FOR UPDATE. En MySQL, la tarea
        específica para generar un identificador único en realidad
        puede realizarse utilizando un sólo acceso a la tabla:
      
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1); SELECT LAST_INSERT_ID();
        La sentencia SELECT simplemente recupera la
        información del identificador (relativa a la conexión actual).
        No accede ninguna tabla.
      
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.

