ragnar_ok
@ragnar_ok

Как увеличивать счетчик в условиях конкуренции?

MySQL InnoDB. Дана таблица со счетчиком.

create table foo
(
    entity_id        int unsigned not null
        primary key,
    count int unsigned not null
)


Сначала с помощью select ... for update проверяется существование записи по primary, и, если записи нет, то происходит insert, иначе update с увеличением счетчика на "1". В случае, если записи нет, при "одновременных" запросах закономерно получаю ошибку дубликата (уровень изоляции read committed).

session1> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

session1> start transaction;
Query OK, 0 rows affected (0.00 sec)

session2> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

session2> start transaction;
Query OK, 0 rows affected (0.00 sec)

session1> select * from foo where entity_id = 8 for update;
Empty set (0.00 sec)

session2> select * from foo where entity_id = 8 for update;
Empty set (0.00 sec)

session1> insert into foo (entity_id, count) values (8, 1);
Query OK, 1 row affected (0.00 sec)

session1> commit;
Query OK, 0 rows affected (0.01 sec)

session2> insert into foo (entity_id, count) values (8, 1);
ERROR 1062 (23000): Duplicate entry '8' for key 'foo.PRIMARY'


Можно ли решить указанным ниже способом? Если произойдет ошибка дублирующегося ключа, то будет ли установлена эксклюзивная блокировка на эту запись?

insert into foo (entity_id, count)
values (8, 1)
on duplicate key update count = count + 1;


Если так, то выходит, что `select ... for update` для решения задачи не нужен в обоих случаях (когда записи нет и когда запись есть)? Оптимальнее сразу выполнять запрос ниже без предварительного `select ... for update` в явно открытой транзакции?
  • Вопрос задан
  • 94 просмотра
Решения вопроса 1
yesbro
@yesbro
Думаю, помогаю думать
Да, лучше использовать конструкцию

insert into foo (entity_id, count)
values (8, 1)
on duplicate key update count = count + 1;
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы