Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何使用选择。。。用于更新尚未存在的记录_Mysql_Database - Fatal编程技术网

Mysql 如何使用选择。。。用于更新尚未存在的记录

Mysql 如何使用选择。。。用于更新尚未存在的记录,mysql,database,Mysql,Database,假设有一个表MYTABLE有两列 SERIALNUMBER,其中SERIALNUMBER是唯一的用户名 多个连接可能会尝试使用相同的序列号(比如1)更新用户名 因此,我提出疑问: 从MYTABLE(其中SERIALNUMBER=1)中选择用户名进行更新 如果此查询返回行表示记录已存在,我将发出更新 更新MYTABLE集合USERNAME=WHERE SERIALNUMBER=1 Else记录不存在,我发出insert 插入MYTABLE SERIALNUMBER,用户名值为1 最后我发布 承诺

假设有一个表MYTABLE有两列

SERIALNUMBER,其中SERIALNUMBER是唯一的用户名

多个连接可能会尝试使用相同的序列号(比如1)更新用户名

因此,我提出疑问:

从MYTABLE(其中SERIALNUMBER=1)中选择用户名进行更新

如果此查询返回行表示记录已存在,我将发出更新

更新MYTABLE集合USERNAME=WHERE SERIALNUMBER=1

Else记录不存在,我发出insert

插入MYTABLE SERIALNUMBER,用户名值为1

最后我发布

承诺

预期行为:

查询中包含相同SERIALNUMBER的连接应在SELECT处等待。。对于UPDATE语句

若记录已经存在,则每个连接都应使用其持有的SERIALNUMBER逐个更新该记录

如果记录不存在,由于SERIALNUMBER不存在,第一个连接为其持有的SERIALNUMBER授予了锁。它的间隙锁如果没有错,则应插入新记录,随后的连接在访问锁时应发现记录已存在。因此,他们应该更新现有记录

实际行为:

若记录已经存在,它将按预期工作,并且每个连接都使用其用户名更新记录

若记录不存在,所有连接将同时尝试插入新记录。其中一个成功,其余的则例外。对于不同的隔离级别,例外情况是不同的

对于InnoDB的默认可重复读取,它是:

MySQL错误代码:1213,SQLState:40001,错误:在 试图得到锁;尝试重新启动事务

对于READ COMMITTED,它是:

MySQL错误代码:1062,SQLState:23000,错误:重复条目“1” 对于键“SERIALNUMBER”

问题陈述:


我想知道如何防止连接同时尝试为相同字段值创建新记录,同时我想允许同时创建记录,只要字段值不同

您这样做是错误的。您应该使用INSERT INTO。。。在重复密钥更新时。。。这样,即使您没有使用事务,操作也是完全原子化的。您这样做是错误的。您应该使用INSERT INTO。。。在重复密钥更新时。。。这样,即使不使用事务,操作也是完全原子化的。