Я стараюсь сформулировать свой комментарий как более длинное объяснение. Предпосылки: InnoDB и VALUE имеют уникальный ключ или первичный ключ.
Начиная с примера OPS
0. BEGIN transaction TX1
1. TX1 performs SELECT VALUE 10
2. TX1 performs INSERT VALUE 10 since it does not exist
3. TX1 performs SELECT VALUE 20
4. TX1 performs INSERT VALUE 20 since it does not exist
5. BEGIN transaction TX2 in a different session, using a different connection
6. TX2 performs SELECT VALUE 10
7. TX2 performs INSERT VALUE 10 since TX1 hasn't committed yet
TX2 will block here until TX1 finishes, if TX1 rolls back this step succeedes,
if TX1 commits, you get an error here.
Для предотвращения этой ситуации использовать FOR UPDATE
суффикса для SELECT
запроса:
0. BEGIN transaction TX1
1. TX1 performs SELECT VALUE 10 FOR UPDATE
2. TX1 performs INSERT VALUE 10 since it does not exist
3. TX1 performs SELECT VALUE 20 FOR UPDATE
4. TX1 performs INSERT VALUE 20 since it does not exist
5. BEGIN transaction TX2 in a different session, using a different connection
6. TX2 performs SELECT VALUE 10 FOR UPDATE
based on the `FOR UPDATE` condition, TX2 will block here until TX1 finishes.
If TX1 commits, the result will be the row TX1 committed, if TX1 rolls back,
this query returns an empty result.
Используя FOR UPDATE
ключевые слова, вы можете избежать этого TX2 не удается, и всегда использует самые последние данные - он вызывает создание блокировок строк (поэтому, используйте с осторожностью). Однако, будьте в курсе тупиков (Database Deadlock in SELECT FOR UPDATE; всегда «блокировка» в том же порядке)
Является ли значение уникальным ключом? Попробуйте «выбрать VALUE FROM TABLE * FOR UPDATE *», чтобы заблокировать результаты, полученные вами по запросу выбора, см. Https://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html. – MrTux
Почему вы используете 2 ссылки? Связаны ли они с отдельными серверами (ведущий/ведомый)? – Jaydee
@MrTux да, значение является уникальным ключом. Поблагодарите. –