mysql - 避免原子事务中的唯一违规

标签 mysql

可以在 MySQL 中创建原子事务吗?

假设我有包含这些行的表“类别”:

id|name
--|---------
1 |'tablets'
2 |'phones'

name 列是我的主键。

如果我尝试:

START TRANSACTION;
update "category" set name = 'phones' where id = 1;
update "category" set name = 'tablets' where id = 2;
COMMIT;

我得到:

ERROR:  duplicate key value violates unique constraint 
"category_name_key"
DETAIL:  Key (name)=(tablets) already exists.

我的期望是约束检查应该只在提交期间完成。这对 MySQL 来说可能吗?

最佳答案

目前在 MySQL 中不可能有这样的事情。 根据 mysql doc

Like MySQL in general, in an SQL statement that inserts, deletes, or updates many rows, InnoDB checks UNIQUE and FOREIGN KEY constraints row-by-row. When performing foreign key checks, InnoDB sets shared row-level locks on child or parent records it has to look at. InnoDB checks foreign key constraints immediately; the check is not deferred to transaction commit. According to the SQL standard, the default behavior should be deferred checking. That is, constraints are only checked after the entire SQL statement has been processed. Until InnoDB implements deferred constraint checking, some things will be impossible, such as deleting a record that refers to itself using a foreign key.

要在 Mysql 中执行此操作,请使用中间表,以便不会发生相同的问题,但目前在 mysql 中没有干净的方法来执行此操作。

它可能在其他数据库中,如 Postgresql您可以在其中设置模式以在事务提交后检查约束

SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE }

关于mysql - 避免原子事务中的唯一违规,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37755797/

相关文章:

mysql - 格式化 Excel,列以获得 hh :mm:ss when they are listed that way 的总和

MySQL "in"语句

MySQL 对行数 <10M 的表进行分区

php - 使用PHP连接远程MySQL错误

mysql - MySQL最大连接数,适当关闭连接

Mysql触发器创建查询-语法错误

mysql - 无法在 MySql 表中插入超过 33138 行

javascript - 如何在 node.js 上连接 reactJS 和 mysql

python - 命令 "python setup.py egg_info"失败,错误代码 1 in/tmp/pip-build-hg0dbjgz/mysqlclient/

mysql - 在 MySQL 中使用 Case 加入 Group By 和 Order