“ElasticSearch基础:并发控制”的版本间差异
跳到导航
跳到搜索
(建立内容为“category:ElasticSearch == 关于 == <syntaxhighlight lang="java" highlight=""> </syntaxhighlight>”的新页面) |
无编辑摘要 |
||
第2行: | 第2行: | ||
== 关于 == | == 关于 == | ||
一般类似 MySQL 都是通过加锁确保数据原子性,在 Elasticsearch 中主要是通过 '''乐观锁''' 确保文档的原子性。 | |||
Elasticsearch 的乐观锁是基于'''版本号'''实现的:文档的元数据中 '''_seq_no'''('''version''')代表当前文档的版本号,每次更新、删除文档的时候,版本号都会加 1。 | |||
* Elasticsearch 7.5.x 使用 '''_seq_no''' 结合 '''_primary_term''' 字段实现乐观锁控制。 | |||
=== 示例验证 === | |||
# 插入一个文档: | |||
#: <syntaxhighlight lang="java" highlight=""> | |||
PUT /order/_doc/2 | |||
{ | |||
"id": 1, | |||
"status": 1, | |||
"total_price": 100, | |||
"create_time": "2019-12-12 12:20:22" | |||
} | |||
</syntaxhighlight> | |||
# 查询该文档,观察版本号: | |||
#: <syntaxhighlight lang="java" highlight=""> | |||
GET /order/_doc/2 | |||
</syntaxhighlight> | |||
#: <syntaxhighlight lang="java" highlight="6,7"> | |||
{ | |||
"_index" : "order", | |||
"_type" : "_doc", | |||
"_id" : "2", | |||
"_version" : 1, | |||
"_seq_no" : 6, // 版本号是6 | |||
"_primary_term" : 1, // 所在主分区是1 | |||
"found" : true, | |||
"_source" : { | |||
"id" : 1, | |||
"status" : 1, | |||
"total_price" : 100, | |||
"create_time" : "2019-12-12 12:20:22" | |||
} | |||
} | |||
</syntaxhighlight> | |||
# 以指定的版本号更新数据: | |||
#: if_seq_no 参数指定文档的版本号,if_primary_term 参数指定文档所在的主分区,如果 ES 发现文档当前的版本号与指定的版本号相等,就会更新文档,否则直接忽略(报错)。 | |||
#: <syntaxhighlight lang="java" highlight=""> | |||
PUT /order/_doc/2?if_seq_no=6&if_primary_term=1 | |||
{ | |||
"id": 1, | |||
"status": 2, | |||
"total_price": 300, | |||
"create_time": "2019-12-12 12:20:22" | |||
} | |||
</syntaxhighlight> | |||
# 重复执行上面的语句,ES 就会输出下面的错误提示:版本冲突 (version conflict): | |||
#: <syntaxhighlight lang="java" highlight=""> | |||
{ | |||
"error": { | |||
"root_cause": [ | |||
{ | |||
"type": "version_conflict_engine_exception", | |||
"reason": "[2]: version conflict, required seqNo [6], primary term [1]. current document has seqNo [7] and primary term [1]", | |||
"index_uuid": "CRQJQH4uTA2ffetowYCMNA", | |||
"shard": "0", | |||
"index": "order" | |||
} | |||
], | |||
"type": "version_conflict_engine_exception", | |||
"reason": "[2]: version conflict, required seqNo [6], primary term [1]. current document has seqNo [7] and primary term [1]", | |||
"index_uuid": "CRQJQH4uTA2ffetowYCMNA", | |||
"shard": "0", | |||
"index": "order" | |||
}, | |||
"status": 409 | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> |
2021年5月20日 (四) 20:57的版本
关于
一般类似 MySQL 都是通过加锁确保数据原子性,在 Elasticsearch 中主要是通过 乐观锁 确保文档的原子性。
Elasticsearch 的乐观锁是基于版本号实现的:文档的元数据中 _seq_no(version)代表当前文档的版本号,每次更新、删除文档的时候,版本号都会加 1。
- Elasticsearch 7.5.x 使用 _seq_no 结合 _primary_term 字段实现乐观锁控制。
示例验证
- 插入一个文档:
PUT /order/_doc/2 { "id": 1, "status": 1, "total_price": 100, "create_time": "2019-12-12 12:20:22" }
- 查询该文档,观察版本号:
GET /order/_doc/2
{ "_index" : "order", "_type" : "_doc", "_id" : "2", "_version" : 1, "_seq_no" : 6, // 版本号是6 "_primary_term" : 1, // 所在主分区是1 "found" : true, "_source" : { "id" : 1, "status" : 1, "total_price" : 100, "create_time" : "2019-12-12 12:20:22" } }
- 以指定的版本号更新数据:
- if_seq_no 参数指定文档的版本号,if_primary_term 参数指定文档所在的主分区,如果 ES 发现文档当前的版本号与指定的版本号相等,就会更新文档,否则直接忽略(报错)。
PUT /order/_doc/2?if_seq_no=6&if_primary_term=1 { "id": 1, "status": 2, "total_price": 300, "create_time": "2019-12-12 12:20:22" }
- 重复执行上面的语句,ES 就会输出下面的错误提示:版本冲突 (version conflict):
{ "error": { "root_cause": [ { "type": "version_conflict_engine_exception", "reason": "[2]: version conflict, required seqNo [6], primary term [1]. current document has seqNo [7] and primary term [1]", "index_uuid": "CRQJQH4uTA2ffetowYCMNA", "shard": "0", "index": "order" } ], "type": "version_conflict_engine_exception", "reason": "[2]: version conflict, required seqNo [6], primary term [1]. current document has seqNo [7] and primary term [1]", "index_uuid": "CRQJQH4uTA2ffetowYCMNA", "shard": "0", "index": "order" }, "status": 409 }