Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL:Como obter bloqueio de transação em nível de linha em vez de bloqueio de tabela


Pode ser útil ver como essa consulta é realmente executada pelo MySQL:
select * from tbl_codes where available = 1 order by rand() limit 1 for update

Isso lerá e classificará todas as linhas que correspondem ao WHERE condição, gere um número aleatório usando rand() em uma coluna virtual para cada linha, classifique todas as linhas (em uma tabela temporária) com base nessa coluna virtual e, em seguida, retorne as linhas para o cliente do conjunto classificado até o LIMIT é alcançado (neste caso apenas um). O FOR UPDATE afeta o bloqueio feito por toda a instrução durante a execução e, como tal, a cláusula é aplicada à medida que as linhas são lidas dentro do InnoDB , não à medida que são devolvidos ao cliente.

Deixando de lado as implicações óbvias de desempenho acima (é terrível), você nunca obterá um comportamento de bloqueio razoável.

Resposta curta:
  1. Selecione a linha desejada usando RAND() ou qualquer outra estratégia de sua preferência, para encontrar a PRIMARY KEY valor dessa linha. Ex.:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1
  2. Bloqueie a linha desejada usando sua PRIMARY KEY só. Por exemplo:SELECT * FROM tbl_codes WHERE id = N

Espero que isso ajude.