"Может ли когда-нибудь быть случай, когда некоторые части ЗНАЧЕНИЙ удалось вставить/обновить в базу данных, но остальные не были вставлены/обновлены, возможно, из-за какой-то ошибки/сбоя/нехватки памяти в базе данных? и т. д.?"
Поздний ответ, но, возможно, интересный: [ON DUPLICATE KEY] UPDATE
не является строго атомарным для отдельных строк (ни для MyISAM
, ни для InnoDB
), но он будет атомарным в отношении ошибок.
Какая разница? Ну, это иллюстрирует потенциальную проблему в предположении строгой атомарности:
CREATE TABLE `updateTest` (
`bar` INT(11) NOT NULL,
`foo` INT(11) NOT NULL,
`baz` INT(11) NOT NULL,
`boom` INT(11) NOT NULL,
PRIMARY KEY (`bar`)
)
COMMENT='Testing'
ENGINE=MyISAM;
INSERT INTO `updateTest` (`bar`, `foo`, `baz`, `boom`) VALUES (47, 1, 450, 2);
INSERT
`updateTest`
(`bar`, `foo`, `baz`, `boom`)
VALUES
(47, 0, 400, 5)
ON DUPLICATE KEY UPDATE
`foo` = IF(`foo` = 1, VALUES(`foo`), `foo`),
`baz` = IF(`foo` = 1, VALUES(`baz`), `baz`),
`boom` = IF(`foo` = 1, VALUES(`boom`), `boom`);
(47, 1, 450, 2)
превратится в (47, 0, 450, 2)
, а не в (47, 0, 400, 5)
. Если вы предполагаете строгую атомарность (что не означает, что вы должны это делать; вы можете предпочесть такое поведение), этого не должно происходить — foo
определенно не должно изменяться до тех пор, пока значения других столбцов не станут даже оценивается. foo
должен меняться вместе с другими столбцами — все или ничего.
Если я говорю атомарный в отношении ошибок, я имею в виду, что если вы удалите условие IF()
в приведенном выше примере, которое подчеркивает более строгую ситуацию, например эту...
INSERT INTO `updateTest` (`bar`, `foo`, `baz`, `boom`) VALUES (48, 1, 450, 2);
INSERT
`updateTest`
(`bar`, `foo`, `baz`, `boom`)
VALUES
(48, 0, 400, 5)
ON DUPLICATE KEY UPDATE
`foo` = VALUES(`foo`),
`baz` = VALUES(`baz`),
`boom` = VALUES(`boom`);
... вы всегда будете либо в конечном итоге с (48, 1, 450, 2)
или (48, 0, 400, 5)
после того, как ваше выражение завершится/сбой, и не какое-то промежуточное состояние, например (48, 0, 450, 2)
.
То же самое верно и для поведения UPDATE
, но еще меньше причин жонглировать операторами IF()
, так как вы можете просто поместить свои условные операторы в предложение WHERE
.
В заключение: вне крайних случаев у вас есть атомарность для операторов с одной строкой, даже при использовании MyISAM
. Дополнительную информацию см. в ответе Йоханнеса Х..
person
pinkgothic
schedule
07.10.2014
insert
должен быть атомарным в любой базе данных, совместимой с ACID. - person Gordon Linoff   schedule 05.02.2014