mysql是否在Single查询中多次插入原子?

时间:2014-02-05 17:27:18

标签: mysql sql insert sql-update atomic

我在单个查询中进行了多次插入:

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查询,是否可以顺利插入/更新查询中指定的所有值,或者不会插入/更新任何值?

4 个答案:

答案 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对于单行(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`);

(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