【问题标题】:Are single mysql statements atomic in MyISAM and InnoDB?MyISAM 和 InnoDB 中的单个 mysql 语句是原子的吗?
【发布时间】:2011-12-05 18:19:55
【问题描述】:

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

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

在不使用事务的情况下,是否保证不管引擎类型如何mysql_affected_rows() 的值对于一个客户端来说是1 而对于另一个客户端来说是0

【问题讨论】:

标签: php mysql database transactions atomic


【解决方案1】:

是和否:-)

在这两种情况下,access is serialised(假设您使用的是 InnoDB 之类的事务引擎)因为它们命中同一行,所以它们不会相互干扰。换句话说,语句原子的。

但是,受影响的行数实际上取决于您在打开连接时设置的配置。 page for mysql_affected_rows() 有话要说(我的大胆):

对于 UPDATE 语句,默认情况下,affected-rows 值是实际更改的行数。如果在连接 mysqld 时为 mysql_real_connect() 指定 CLIENT_FOUND_ROWS 标志,则受影响的行值是行数 "found";即由 WHERE 子句匹配。

来自the mysql_real_connect page

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

因此,对于 CLIENT_FOUND_ROWS 被配置会发生什么,受影响的行:

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

与数据是否更改无关只有哪些行匹配。这对于两个查询都是 1。 p>

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

如果您想要 same 行为而不管该设置(仅显示更改),您可以使用类似:

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

【讨论】:

  • 你的意思是说单语句更新对于 MyIASM 来说不是原子的?
  • 一个快速的谷歌建议 MyISAM 主要是原子的,只要你从不杀死线程或查询。 bugs.mysql.com/bug.php?id=51193
  • @sanmai:来自dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.html:锁定读取、UPDATE 或DELETE 通常会在SQL 语句处理过程中扫描的每条索引记录上设置记录锁。
  • @MyISAM 是一个瓦罐,应该与所有 NoSQL 数据库一起归入它所属的地方:-)
  • @sanmai,对不起,误读了查询,以为是where c1 = 'clean'
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2012-07-15
    • 2015-09-26
    • 2011-04-18
    • 2012-03-01
    • 2011-05-14
    • 2012-01-13
    • 2012-04-14
    • 2013-09-25
    • 2015-07-18
    相关资源
    最近更新 更多