
Es común tener varios procesos que trabajan sobre un mismo recurso pero que no deben interferir uno con otro. En un solo procesador se resuelve facilmente (con los llamados locks o semáforos). Hacerlo en forma distribuida, cuando los procesos están en distintas CPUs es mas complicado. Con MySQL podemos implementar semáforos distribuidos de una forma extremadamente simple y que funciona en un solo servidor o en muchos.
Pongamos un ejemplo: tengo dos programas A y B. A quiere actualizar un stock sumandole 10 unidades y el B quiere dar de baja 3 unidades. El stock original es 100. Si A lee la cantidad 100, luego el B lee la misma cantidad antes de que A grabe 110 en la base de datos. Entonces A graba 110, pero B hace 100-3=97 y graba 97. Tendríamos que implementar algo que evite que B lea el stock antes de que A termine su operación (y no voy a hablar de transacciones, este es un ejemplo para ilustrar semáforos!).
Con las funciones de MySQL get_lock() y release_lock() podemos evitar estos conflictos.
Si A ejecuta algo como select get_lock('tocarstocks', 30) le va a devolver un 1 si el servidor le "otorga el lock". Cuando termina de trabajar tienen que hacer un select release_lock('tocarstocks').
Cuando B quiera tocar un stock tiene que ejecutar el mismo get_lock(). Si devuelve 1 significa que A no está ejecutando el código entre el get_lock() y el release_lock(), asi que es seguro modificar datos. Si A todavia no hizo el realease_lock() entonces B va a quedar bloqueado hasta que lo haga, o hasta que se supere el timeout (el 30 que pusimos como ejemplo). En este caso el select le va a devolver 0 (cero) y debe volver a intentar el get_lock o darse por vencido.
Lo interesante de esto es que funciona en una sola CPU, pero tambien cuando tenemos distintos procesos en distintos servidores y todos trabajando sobre la misma base de datos.