sql >> Base de Datos >  >> RDS >> Mysql

MySQL:cómo lograr el bloqueo de transacciones a nivel de fila en lugar del bloqueo de tablas

Puede ser útil ver cómo MySQL ejecuta realmente esta consulta:

select * from tbl_codes where available = 1 order by rand() limit 1 for update

Esto leerá y clasificará todas las filas que coincidan con WHERE condición, generar un número aleatorio usando rand() en una columna virtual para cada fila, ordene todas las filas (en una tabla temporal) en función de esa columna virtual y luego devuelva las filas al cliente desde el conjunto ordenado hasta el LIMIT se alcanza (en este caso sólo uno). El FOR UPDATE afecta el bloqueo realizado por toda la declaración mientras se ejecuta y, como tal, la cláusula se aplica a medida que se leen las filas dentro de InnoDB , no a medida que se devuelven al cliente.

Dejando a un lado las obvias implicaciones de rendimiento de lo anterior (es terrible), nunca obtendrá un comportamiento de bloqueo razonable.

Respuesta corta:

  1. Seleccione la fila que desee, usando RAND() o cualquier otra estrategia que desee, para encontrar la PRIMARY KEY valor de esa fila. Ej.:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1
  2. Bloquee la fila que desee usando su PRIMARY KEY solamente. Por ejemplo:SELECT * FROM tbl_codes WHERE id = N

Espero que eso ayude.