pil*_*ght 9 mysql sql insert atomic sql-update
我在做一个多刀片单查询:
INSERT INTO table (c1, c2) VALUES (1,2),
(2,3),
(3,4),......
ON DUPLICATE KEY UPDATE c2 = VALUES(c2)
Run Code Online (Sandbox Code Playgroud)
现在假设在查询中指定了超过数万个VALUES(因此省略号)....
有没有一种情况,VALUES的某些部分设法在数据库中插入/更新,但其余部分可能由于某种db错误/故障/内存耗尽等而未插入/更新?
mysql查询是ALL还是Nothing?
对于每个执行的mysql查询,是否可以顺利插入/更新查询中指定的所有值,或者不会插入/更新任何值?
Joh*_* H. 14
ACID (原子性,一致性,隔离性,持久性)属性用于描述数据库中的此类行为.只有在我们处理并发修改时,原子性才是重要的.为确保一致性,必须达到一定程度的隔离.但是,运行的隔离多个事务越多,DBMS通常具有的性能就越低.所以有一个所谓的" 隔离级别 ",它说明了DBMS中可能发生的错误,哪些不可能.
现在,MySQL实现了INNODB数据库中的所有隔离级别,您可以为每个事务选择:https://dev.mysql.com/doc/refman/5.1/en/set-transaction.html
MyIsam数据库不支持事务,但是单个操作应该以原子方式运行.(来源:https://dev.mysql.com/doc/refman/5.0/en/ansi-diff-transactions.html).但请注意,这并不保证在一次操作中读取和写入之间的数据不会更改 - DBMS术语中的原子性仅表示操作已完全完成或完全跳过.它不保证隔离,一致性或耐用性.
“是否有可能因为某种数据库错误/故障/内存耗尽等原因,VALUES 的某些部分设法插入/更新到数据库中,但其余部分没有插入/更新? ”
迟到的答案,但也许很有趣:对于单行(既不是 for也不是 for )[ON DUPLICATE KEY] UPDATE不是严格原子的,但它在错误方面是原子的。MyISAMInnoDB
有什么不同?好吧,这说明了假设严格原子性的潜在问题:
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`);
Run Code Online (Sandbox Code Playgroud)
(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`);
Run Code Online (Sandbox Code Playgroud)
...你将永远要么结了(48, 1, 450, 2) 或 (48, 0, 400, 5)你的发言结束后/坠毁,而不是一些中间状态一样(48, 0, 450, 2)。
的行为也是如此UPDATE,但没有理由在IF()那里处理语句,因为您可以将条件WHERE语句放入您的子句中。
结论:在边缘情况之外,您确实具有单行语句的原子性,即使使用MyISAM. 有关更多信息,请参阅Johannes H. 的回答。
| 归档时间: |
|
| 查看次数: |
9095 次 |
| 最近记录: |