Mysql 如何使用选择。。。用于更新尚未存在的记录
假设有一个表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” 问题陈述:Mysql 如何使用选择。。。用于更新尚未存在的记录,mysql,database,Mysql,Database,假设有一个表MYTABLE有两列 SERIALNUMBER,其中SERIALNUMBER是唯一的用户名 多个连接可能会尝试使用相同的序列号(比如1)更新用户名 因此,我提出疑问: 从MYTABLE(其中SERIALNUMBER=1)中选择用户名进行更新 如果此查询返回行表示记录已存在,我将发出更新 更新MYTABLE集合USERNAME=WHERE SERIALNUMBER=1 Else记录不存在,我发出insert 插入MYTABLE SERIALNUMBER,用户名值为1 最后我发布 承诺
我想知道如何防止连接同时尝试为相同字段值创建新记录,同时我想允许同时创建记录,只要字段值不同您这样做是错误的。您应该使用INSERT INTO。。。在重复密钥更新时。。。这样,即使您没有使用事务,操作也是完全原子化的。您这样做是错误的。您应该使用INSERT INTO。。。在重复密钥更新时。。。这样,即使不使用事务,操作也是完全原子化的。