Elasticsearch教程(16) 乐观锁并发控制 if_seq_no 和 if_primary_term 详解


if_seq_no 和 if_primary_term 是用来并发控制,他们和version不同,version属于当个文档,而seq_no属于整个index。

1 创建一简单文档

PUT /pigg_test/_doc/1
{
  "name": "冬哥",
  "age": 33,
  "interest": ["music", "food"]
}

返回结果如下:
注意最后2个值,_seq_no在文档跟新一次后都会+1,_primary_term表示文档所在主分片的编号

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

用GET查看文档

GET pigg_test/_doc/1
{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "冬哥",
    "age" : 33,
    "interest" : [
      "music",
      "food"
    ]
  }
}

2. 修改文档,_seq_no会+1

PUT /pigg_test/_doc/1
{
  "name": "冬哥",
  "age": 32,
  "interest": ["music", "food"]
}

返回如下:

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

3. 修改文档,带上if_seq_no和if_primary_term

修改时,if_seq_no和if_primary_term设置为被修改前的当前值,上面第2步结果_seq_no=1,所以这里要设置if_seq_no=1,分片也没有换,所以if_primary_term=1

PUT /pigg_test/_doc/1?if_seq_no=1&if_primary_term=1
{
  "name": "冬哥",
  "age": 31,
  "interest": ["music", "food"]
}

返回说明修改成功,_seq_no又+1,变成了2

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

4. 修改文档,模拟并发

模拟并发,再次请求加上if_seq_no=1&if_primary_term=1

PUT /pigg_test/_doc/1?if_seq_no=1&if_primary_term=1
{
  "name": "冬哥",
  "age": 31,
  "interest": ["music", "food"]
}

因为seq_no已经变成了2,但是上面请求时还是if_seq_no=1,所以会报错,错误原因详细看reason的值。

{
  "error" : {
    "root_cause" : [
      {
        "type" : "version_conflict_engine_exception",
        "reason" : "[1]: version conflict, required seqNo [1], primary term [1]. current document has seqNo [2] and primary term [1]",
        "index_uuid" : "iGtCA6A_TyeQeHrMM9_c7A",
        "shard" : "0",
        "index" : "pigg_test"
      }
    ],
    "type" : "version_conflict_engine_exception",
    "reason" : "[1]: version conflict, required seqNo [1], primary term [1]. current document has seqNo [2] and primary term [1]",
    "index_uuid" : "iGtCA6A_TyeQeHrMM9_c7A",
    "shard" : "0",
    "index" : "pigg_test"
  },
  "status" : 409
}

5. 删除文档,_seq_no还是会+1

DELETE pigg_test/_doc/1

删除后_seq_no变成了3,如果再次创建id=1的文档时,_seq_no还是会+1,变成4

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

6. seq_no递增属于整个index,而不是单个文档

这个时候再创建一个id=2的文档

PUT /pigg_test/_doc/2
{
  "name": "珣爷",
  "age": 28,
  "interest": ["music", "sleep"],
  "about": "I am a tester"
}

返回中_seq_no=4,这个是id=1的seq_no上再加一的,所以说_seq_no递增是属于整个索引。
但是每个文档依旧有自己的seq_no值,更新一个文档时,还是用该文档的seq_no控制并发。
当index中任何文档修改或新增,seq_no都会+1。
例如id=1的文档创建后seq_no=1,
那么id=2的文档创建后,seq_no=2,
再然后id=1的文档修改后,seq_no=3
再对id=2的文档修改,要并发控制,if_seq_no得=2

{
  "_index" : "pigg_test",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 4,
  "_primary_term" : 1
}
  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑟 王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值