"Can there ever be a case in which some parts of the VALUES managed to get inserted/updated in the database but the rest did not get inserted/updated possibly due to some sort of db error/failure/memory-running-out etc?"
Late answer, but perhaps interesting: [ON DUPLICATE KEY] UPDATE
is not strictly atomic for single rows (neither for MyISAM
, nor for InnoDB
), but it will be atomic in regards to errors.
What's the difference? Well, this illustrates the potential problem in assuming strict atomicity:
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)
will have turned into (47, 0, 450, 2)
, and not into (47, 0, 400, 5)
. If you assume strict atomicity (which is not to say you should; you might prefer this behaviour), that shouldn't happen - foo
should certainly not change before the other columns' values are even evaluated. foo
should change together with the other columns - all or nothing.
If I say atomic in regards to errors, I mean that if you remove the IF()
condition in the above example that's highlighting the stricter situation, like this...
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`);
...you will always either end up with (48, 1, 450, 2)
or (48, 0, 400, 5)
after your statement has finished/crashed, and not some in-between state like (48, 0, 450, 2)
.
The same is true for the behaviour of UPDATE
, but there's even less of a reason to juggle IF()
statements there, since you can just put your conditionals into your WHERE
clause there.
In conclusion: Outside of edge-cases, you do have atomicity for single-row statements, even using MyISAM
. See Johannes H.'s answer for further information.