我在单个查询中进行了多次插入:
INSERT INTO table (c1, c2) VALUES (1,2),
(2,3),
(3,4),......
ON DUPLICATE KEY UPDATE c2 = VALUES(c2)
现在假设查询中指定了超过数万个VALUES(因此省略号)....
是否会出现这样的情况:VALUES的某些部分设法在数据库中插入/更新,但其余部分未插入/更新可能是由于某种类型的db错误/故障/内存耗尽等?
mysql查询ALL还是Nothing?
对于每个执行的mysql查询,是否可以顺利插入/更新查询中指定的所有值,或者不会插入/更新任何值?
答案 0 :(得分:14)
ACID(原子性,一致性,隔离性,持久性)属性用于描述数据库中的此类行为。只有在我们处理concurrent modifications时,原子性才是重要的。为确保一致性,必须达到一定程度的隔离。但是,运行的隔离多个事务越多,DBMS通常具有的性能就越低。所以有一个所谓的“isolation level”,它说明了在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术语中的原子性仅表示操作已完全完成或完全跳过。它不保证隔离,一致性或耐用性。
答案 1 :(得分:4)
“是否曾经存在这样的情况:VALUES的某些部分设法在数据库中插入/更新但其余部分未插入/更新可能是由于某种类型的db错误/故障/内存 - 逃跑等?“
回答很晚,但也许很有意思:[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
应与其他列一起更改 - 全部或全部。
如果我在错误方面说 atomic ,我的意思是,如果您删除上述示例中的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
,您也确实具有单行语句的原子性。请参阅Johannes H.'s answer for further information。
答案 2 :(得分:1)
表存储引擎是InnoDB,是的,操作肯定是原子操作,不能进行部分插入。我认为默认引擎MyISAM不是这样,因为它不符合ACID并且不支持交易。
答案 3 :(得分:0)
这样的单一陈述是。如果您需要多次调用以原子方式执行操作,则可以在大多数关系数据库中使用transactions。