ElasticSearch基于_version进行乐观锁来并发控制,version可分为ElasticSearch内部维护的version和外部自己维护的external version
1. ElasticSearch内部的_version
第一次创建一个document的时候,它的_version内部版本号就是1;以后,每次对这个document执行修改或者删除操作,都会对这个_version版本号自动加1;哪怕是删除,也会对这条数据的版本号加1
# 先创建一条数据
PUT /test_index/test_type/10
{
"test_field": "test test"
}
用户A通过Kibana进行修改数据,并且带上版本号
{
"_index": "test_index",
"_type": "test_type",
"_id": "10",
"_version": 2, # 注意这里的version变成了2
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
用户B在后台进行修改数据
from elasticsearch import Elasticsearch
es = Elasticsearch(hosts="ip:port")
body = {
"test_field": "test client 2"
}
# 带上数据的版本号,忽略_version不相等发生的异常
result = es.index(index="test_index", doc_type="test_type", id=10, body=body, version=1, ignore=[409])
print(result)
"""
{'error': {'root_cause': [{'type': 'version_conflict_engine_exception', 'reason': '[test_type][10]: version conflict, current version [2] is different than the one provided [1]', 'index_uuid': 'C_HGsY-aTlOD7A9DTMEftQ', 'shard': '2', 'index': 'test_index'}], 'type': 'version_conflict_engine_exception', 'reason': '[test_type][10]: version conflict, current version [2] is different than the one provided [1]', 'index_uuid': 'C_HGsY-aTlOD7A9DTMEftQ', 'shard': '2', 'index': 'test_index'}, 'status': 409}
"""
2. ElasticSearch外部的external version
用户C在后台进行修改数据
body = {
"test_field": "test client 10"
}
# version_type="external" ,version=10 相当于?version=10&version_type=external
result = es.index(index="test_index", doc_type="test_type", id=10, body=body, version=10, version_type="external",ignore=[409])
print(result)
"""
{'_index': 'test_index', '_type': 'test_type', '_id': '10', '_version': 10, 'result': 'updated', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 4, '_primary_term': 1}
"""
3. 内部的_version和外部的external version的区别
"""
version_type=external,唯一的区别在于,_version,只有当你提供的version与es中的_version一模一样的时候,才可以进行修改,只要不一样,就报错;
当version_type=external的时候,只有当你提供的version比es中的_version大的时候,才能完成修改
es,_version=1,?version=1,才能更新成功
es,_version=1,?version>1&version_type=external,才能成功,比如说?version=2&version_type=external
"""