MyISAM和InnoDB中的单个mysql语句是否是原子的?

时间:2011-10-12 01:16:26

标签: php mysql database transactions atomic

例如,我有一列C1 value = 'clean',两个不同的客户在同时运行此查询:

update T1 set C1 = 'dirty' where Id = 1

在不使用交易的情况下,无论引擎类型 保证>一个客户端的mysql_affected_rows()值为1而另一个客户端的值0是否为{{1}}?

2 个答案:

答案 0 :(得分:11)

是和否: - )

在这两种情况下,access is serialised(假设您使用像InnoDB这样的事务引擎),因为它们会碰到同一行,因此它们不会相互干扰。换句话说,语句原子。

但是,受影响的行数实际上取决于打开连接时的配置集。 page for mysql_affected_rows()有这个说法(我的大胆):

  

对于UPDATE语句,默认情况下受影响的行值是实际更改的行数。如果在连接到mysqld时指定了mysql_real_connect()的CLIENT_FOUND_ROWS标志,则受影响的行值是行数“找到”;也就是说,由WHERE子句匹配。

来自the mysql_real_connect page

  

CLIENT_FOUND_ROWS:返回找到(匹配)行的数量,而不是已更改行的数量。

因此,就配置 CLIENT_FOUND_ROWS时发生的情况而言,受影响的行为:

UPDATE T1 SET C1 = 'dirty' WHERE id = 1

p>

另一方面,如果CLIENT_FOUND_ROWS 设置,则第二个查询实际上不会更改行(因为它已经填充了'dirty')并且会有一行数为零。

如果您想要相同的行为而不管该设置(仅显示更改),您可以使用以下内容:

UPDATE T1 SET C1 = 'dirty' WHERE id = 1 AND C1 <> 'dirty'

答案 1 :(得分:3)

如果您使用像InnoDB这样的事务存储引擎,则MySQL符合ACID。