跳到主要内容

创建或更新操作

准备数据


CREATE TABLE `film` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键标识',
`title` VARCHAR(100) NOT NULL COMMENT '电影名称',
`release_year` INT COMMENT '发行年份',
`director` VARCHAR(50) COMMENT '导演',
`duration` INT COMMENT '片长(分钟)',
`_openid` VARCHAR(64) COMMENT '权限字段',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='电影表';

INSERT INTO `film` (`id`,`title`,`release_year`,`director`,`duration`,`_openid`)
VALUES
(1,'Inception',2010,'Christopher Nolan',148,'1977683311217119233'),
(2,'The Shawshank Redemption',1994,'Frank Darabont',142,'1977683311217119233'),
(3,'The Godfather',1972,'Francis Ford Coppola',175,'1977683311217119233'),
(4,'The Godfather: Part II',1974,'Francis Ford Coppola',202,'1977683311217119233'),
(5,'The Godfather: Part III',1990,'Francis Ford Coppola',194,'1977683311217119233');

1. 当创建冲突时,进行更新处理

Request


curl -i -X POST http://{{host}}/v1/rdb/rest/v1/film?select=* \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <This is a fake token, please use yours>' \
-H 'Prefer: return=representation, resolution=merge-duplicates' \
-d '{
"id": 1,
"title": "Inception",
"release_year": 2010,
"director": "Nolan",
"duration": 150
}'

Response

HTTP/1.1 201 Created

Header:
content-length: 116
content-range: */2
content-type: application/json; charset=utf-8
preference-applied: return=representation, resolution=merge-duplicates

Body:
[
{
"_openid": "1977683311217119233",
"director": "Nolan",
"duration": 150,
"id": 1,
"release_year": 2010,
"title": "Inception"
}
]

说明:

  • return=representation 表示执行写数据时,返回写入后的数据,配合select 一起使用,默认返回所有字段数据
  • resolution=merge-duplicates 表示当创建冲突时,进行更新处理。冲突依据:当主键或唯一索引存在创建冲突时,进行更新处理
  • content-range: */2 表示受影响行数,此时表示本次请求创建 1 条数据时发生冲突,从而进行更新处理,所以受影响行数为 2

注意

  1. 由于 MySQL 数据库特性限制,resolution=merge-duplicates高并发 场景下存在 死锁 风险,请谨慎使用。
  2. 当使用 resolution=merge-duplicates 时,请确保请求体中包含主键或唯一索引字段。
  3. 在通过 content-range: */2 判断是否发生冲突时,请注意,此时受影响行数为 2,而不是 1,因为此时会进行更新处理,所以受影响行数为 2。

2. 当创建冲突时,进行忽略

Request


curl -i -X POST 'https://{{host}}/v1/rdb/rest/film?select=*' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <This is a fake token, please use yours>' \
-H 'Prefer: resolution=ignore-duplicates,return=representation' \
--data '{
"id": 2,
"title": "12 Angry Men",
"release_year": 1957,
"director": "Sidney Lumet",
"duration": 96
}'

Response

HTTP/1.1 201 Created

Header:
content-length: 125
content-range: */0
content-type: application/json; charset=utf-8
preference-applied: return=representation, resolution=ignore-duplicates

Body:
[
{
"_openid": "1977683311217119233",
"director": "Sidney Lumet",
"duration": 96,
"id": 2,
"release_year": 1957,
"title": "12 Angry Men"
}
]

说明:

  • 当创建冲突时,进行忽略,此时受影响行数为 0, content-range: */0
  • 当创建忽略时,会返回请求的数据。

注意:

  1. 由于 MySQL 数据库特性限制,resolution=merge-duplicates 在高并发场景下存在 死锁 风险,请谨慎使用。
  2. 当使用 upsert 任意策略时,请确保请求体中包含主键或唯一索引字段。
  3. 当使用 resolution=merge-duplicates 时, MySQL 将这种情况视为 ​先尝试插入 再更新,因此:
  • ​插入尝试​:计为 1 行受影响(即使未实际插入)。
  • ​更新操作​:计为 1 行受影响。
  • ​总计返回 2。
  1. 当使用 resolution=ignore-duplicates 时, MySQL 将这种情况视为 ​静默忽略​(不插入也不更新),所以受影响行数是 0。 即使忽略了冲突,仍会消耗一个自增值