在Elasticsearch 7.3中,乐观锁控制是通过_version
字段实现的。每当文档被更新时,Elasticsearch会自动递增文档的_version
版本号。在并发环境下,乐观锁可以通过检查和使用_version
来防止丢失更新的问题。
增(创建)文档时:
当首次创建文档时,Elasticsearch会自动赋予文档一个初始的_version
值(通常是1)。
POST /my_index/_doc/1
{
"message": "Hello World",
"user_id": 123
}
更新文档时使用乐观锁:
在更新文档时,你可以带上期望的当前版本号。只有当实际版本与你提供的版本一致时,更新才会成功。否则,Elasticsearch会返回一个错误,表示版本冲突。
PUT /my_index/_doc/1?version=2&version_type=internal
{
"doc": {
"message": "Updated message"
},
"detect_noop": true
}
这里:
version=2
表示我们期望当前文档的版本是2。version_type=internal
指定我们使用的是Elasticsearch内部维护的版本号。detect_noop=true
可选参数,指示Elasticsearch检测是否实际上没有更改任何字段,即使版本匹配也拒绝noop更新。
如果在请求发出时,文档的实际版本已经不再是2,那么此次更新将会失败,并返回类似于以下的错误响应:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[my_index][1]: version conflict, current [3], provided [2]",
"index_uuid": "some_uuid",
"shard": "0",
"index": "my_index"
}
],
"type": "version_conflict_engine_exception",
"reason": "[my_index][1]: version conflict, current [3], provided [2]",
...
},
"status": 409
}
这样就实现了乐观并发控制,确保在高并发场景下,只有一个更新能够成功执行,从而避免了数据竞争带来的不一致性问题。