Elasticsearch7.9:二、索引并发控制
首先我们需要清楚:
ES 中的文档是不可变更的。如果你更新一个文档,会将文档标记为删除,同时增加一个全新的文档,与此同时文档的 version 字段也会加 1。
那么 es7.x 之后,对应的 version 让然保留着,但是内部乐观锁版本控制是通过另外两个新引入的字段来控制的,分别是:seq_no 和 primary_term,汉语翻译过来就是:序列号 和 主项。
如何进行事务控制呢?
在创建一个新文档时,会为其分配一个初始化的序列号(_seq_no)和主项(_primary_term)。
在此之后如果对文档有新的变更,序列号会递增。我们可以通过 GET api 可查看指定文档当前的序列号和主项。
在调用 INDEX、UPDATE、DELETE api 时,通过在 url 传递参数 if_seq_no 和 if_primary_term 来分别指定 序列号 和 主项,
这样:只有在要操作的文档的序列号和主项为指定值时才会对文档执行指定操作,否则会返回 version_conflict_engine_exception 异常 和 状态码 409。
例如:索引中有如下文档
试图执行以下更新:
POST user/_update/dGuQgm0BTkzY5ivQV2rk?if_seq_no=12&if_primary_term=1 { "doc":{ "date":"2019-10-01T00:23:42" } }
则会返回如下错误:
这样就保证了不会丢失序列号为11,主项为1的操作。
如果 传入的参数与为:if_seq_no=10&if_primary_term=1
则最终更新会成功,通过 GET api 查看你会看到 _seq_no = 11。
外部版本控制
使用外部版本控制,即使用其他数据库作为主要数据存储,这个和原来的方案是一样的,并没有发生什么变化,即:
version + version_type = external