Pergunta

Eu tenho uma tabela Innodb que contém usuários, assim:

+--------------+-----------------------+
| user_id      | name                  |
+--------------+-----------------------+
| 1            | Bob                   |
| 1            | Marry                 |
| 2            | Bob                   |
| 1            | John                  |
| 3            | Bob                   |
| 2            | Marry                 |
+--------------+-----------------------+

Em cada inserção, incremento user_id em 1, por exemplo, o próximo user_id para Bob será 4

Eu uso esta consulta para fazer isso:

INSERT INTO users (user_id, name)
SELECT 1 + coalesce((SELECT max(user_id) FROM users WHERE name='Bob'), 0), 'Bob';

Agora preciso garantir que dois usuários diferentes não adicionem um 'bob' ao mesmo tempo. Não quero dois bobs com user_id 4. Cada um dos IDs de usuário de Bob deve ser diferente.

É possível escrever e atualizar o bloqueio de todas as linhas de Bob quando a consulta de inserção acima é executada? Não posso trancar a tabela inteira porque muitos outros usuários ainda precisam de acesso total às suas linhas. Além disso, todas as linhas devem ser legíveis o tempo todo. Como eu faria isso?

Foi útil?

Solução

Assumindo innodb aqui, você pode usar Selecione ... Modo de bloqueio Para bloquear as linhas quando você as selecionar.

Outras dicas

Para resolver a primeira parte da sua pergunta, crie um índice exclusivo em user_id e nome.

alter table `users` add unique index ak_user_id_name(user_id,name);

Isso impedirá o user_id duplicado, o nome registra.

A resposta para esta pergunta é a mesma que Este. O Innodb bloqueará mais linhas aqui do que você espera por segurança com o registro binário baseado em declaração.

A solução: Use o log binário baseado em linha com o nível de isolamento de leitura-compromisso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top