Я выполняю несколько транзакций одновременно, и возникает случай, когда одна и та же строка проверяется с помощью запроса SELECT FOR UPDATE, и она вставляется или обновляется с помощью INSERT ON DUPLICATE KEY UPDATE.Но это вызывает тупик.
Вот схема таблицы
CREATE TABLE `t` (
`a` varchar(40) NOT NULL,
`b` date NOT NULL,
`c` enum('a','b') COLLATE utf8_bin NOT NULL,
`d` char(12) NOT NULL,
`e` TINYINT(1) UNSIGNED NOT NULL,
PRIMARY KEY (`a, `b`, `c`, `d` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
Ниже приведены операции транзакции.
В транзакции 1:
Start Transaction;
SELECT *
FROM t
WHERE
a= '123'
AND `b` = '2017-01-01'
AND c= 'a'
AND d= '1'
FOR UPDATE;
INSERT INTO t
(`a`, b, `c` , d, e)
VALUES ('123', '2017-01-01', 'a' , '1' , '2')
ON DUPLICATE KEY UPDATE `e` = '2';
Commit;
В транзакции 2:
Start Transaction;
SELECT *
FROM t
WHERE
a= '123'
AND `b` = '2017-01-01'
AND c= 'a'
AND d= '1'
FOR UPDATE;
INSERT INTO t
(`a`, b, `c` , d, e)
VALUES ('123', '2017-01-01', 'a' , '1' , '2')
ON DUPLICATE KEY UPDATE `e` = '2';
Commit;
Блокировка возникает, когда обе транзакции выполнили выбор для обновления и одна из транзакций пытается вставить строку.
ПРИМЕЧАНИЕ : мне нужно выбрать SELECT FOR UPDATE, потому что я веду счет на основе предыдущего результата, прежде чем результат будет обновлен.Deadlock создан из-за вставки.
Вопрос : Как я могу избежать проблемы тупика?