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

Pac*_*ier 6 php mysql database transactions atomic

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

update T1 set C1 = 'dirty' where Id = 1
Run Code Online (Sandbox Code Playgroud)

如果不使用交易,是无论发动机类型保证该值mysql_affected_rows()将是1一个客户端,并0为其他?

pax*_*blo 11

是和否:-)

在这两种情况下,访问都是序列化的(假设您正在使用像InnoDB这样的事务引擎),因为它们在同一行中,因此它们不会相互干扰.换句话说,这些陈述原子的.

但是,受影响的行数实际上取决于打开连接时的配置集.mysql_affected_rows()页面有这个说法(我的粗体):

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

并从mysql_real_connect页面:

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

因此,在发生了什么方面 CLIENT_FOUND_ROWS配置,则受影响的行为:

UPDATE T1 SET C1 = 'dirty' WHERE id = 1
Run Code Online (Sandbox Code Playgroud)

什么做的数据是否发生变化,只有哪些行匹配.对于两个查询,这将是1.

在另一方面,如果CLIENT_FOUND_ROWS没有设置,第二个查询实际上不会改变行(因为它已经与"脏"填充),并且将具有零行计数.

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

UPDATE T1 SET C1 = 'dirty' WHERE id = 1 AND C1 <> 'dirty'
Run Code Online (Sandbox Code Playgroud)