任何一个系统都需要考虑并发请求的场景,ES也不例外,在ES中使用了乐观锁来并发控制的 1、ES如何基于_version进行乐观锁并发控制
PUT /test_index/test_type/3 { "test_field":"test" }第一次创建一个document的时间,它的_version内部版本号是1,以后,每次对这个document执行修改或者删除操作,都会对这个_version版本号自动加1,哪怕是删除,也会对这条数据的版本号加1
再次执行put操作,_version加1了
执行了DELETE操作以后_version加1了 再次执行put操作以后_version加1了
我们可以发现,在删除一个document之后,可以从一个侧面证明,它不是立即物理删除的,因为他的一些版本号等信息还是保留着的,先删除一条document,再重新创建这条document,其实会在delete version基础之上,再把version号加1
如何利用_version进行乐观锁并发控制
1、先构造一条数据出来
PUT /test_index/test_type/6 { "test_field":"test lock" }2、模拟两个客户端,都获取到了同一条数据
GET /test_index/test_type/63、其实一个客户端,先更新一下这个数据,同时带上数据的版本号,确切的说es中的数据的版本号,跟客户端中的数据的版本号是相同的,才能修改
PUT /test_index/test_type/6?version=1 { "test_field":"test lock client 1" }4、另外一个客户端,尝试基于version=1的数据去进行修改,同样带上version版本号
PUT /test_index/test_type/6?version=1 { "test_field":"test lock client 2" }5、在乐观锁成功阻止并发问题之后,尝试正确的完成更新 客户端2重新查看记录version变成了2,
6、基于最新的数据和版本号,去进行修改,修改后,带上最新的版本号,如果并发很大的话,可能需要执行多次请求
乐观锁中还有基于external version进行乐观锁并发控制
external version es提供了一个feature,就是说,你可以不用它提供的内部_version版本号来进行并发控制,可以基于你自己维护的一个版本号来进行并发控制。 表示形式:
?version=1 ?version=1&version_type=external区别: version_type=external,唯一的区别在于,_version,只有当你提供的version与es中的_version一模一样的时候,才可以进行修改,只要不一样,就报错;当version_type=external的时候,只有当你提供的version比es中的_version大的时候,才能完成修改 例如:
_version=1,?version=1,才能更新成功 e_version=1,?version>1&version_type=external,才能成功,比如说?version=2&version_type=external
还是刚才上面那个数据,目前document的version是3了,我们现在用,下面这个去更新肯定会出错
PUT /test_index/test_type/6?version=4 { "test_field":"test lock client 1" }因为version号不一样
但是如果我们使用下面这个就可以更新成功了
PUT /test_index/test_type/6?version=4&version_type=external { "test_field":"test lock client 1" }现在document的version版本号是4了,如果我们还继续用上面的语句更新会发现出错了,这里错误信息就是,你在更新的version号要大于document里面的version号
