1、并发冲突问题
2、图解剖析悲观锁与乐观锁两种并发控制方案
3、图解Elasticsearch内部如何基于_version进行乐观锁并发控制
(1)_version元数据
在第一次创建document时内部的_version的内部版本号就为1,每次多document进行增删改时,_version就自动加1
在delete之后,在进行put数据,内部版本号还在+1,这就侧面说明,在delete之后,数据并没有被删除, 他的内部_version等信息还存在。
(2)在es 7.9版本,是基于if_seq_no和if_primary_term进行乐观锁并发控制
PUT /bobotest/_doc/5/{"name": "lisi","desc": "piaoliang de keai de xiaogege111","age": 15,"tags":"shuaige"}{"_index" : "bobotest","_type" : "_doc","_id" : "5","_version" : 2, #版本号加1"_seq_no" : 17,"_primary_term" : 1,"found" : true,"_source" : {"name" : "lisi","desc" : "piaoliang de keai de xiaogege111","age" : 15,"tags" : "shuaige"}}

验证
先创建filed=test1,然后修改_version=1 filed=test2 后修改_version=2 filed=test3
#创建documentPUT /bobotest/_doc/7/{"filed": "test1"}{"_index" : "bobotest","_type" : "_doc","_id" : "7","_version" : 1,"result" : "created","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 19,"_primary_term" : 1}#修改if_seq_no=19&if_primary_term=1 "filed": "test3"PUT /bobotest/_doc/7?if_seq_no=19&if_primary_term=1{"filed": "test3"}#修改if_seq_no=20&if_primary_term=1 "filed": "test3"PUT /bobotest/_doc/7?if_seq_no=20&if_primary_term=1{"filed": "test4"}正确顺序: test1 -->test3-->test4
并发时
test4和test3同时更新则 test1 -->test3PUT /bobotest/_doc/7?if_seq_no=21&if_primary_term=1 #后改的先到{"filed": "test4"}PUT /bobotest/_doc/7?if_seq_no=21&if_primary_term=1 #先改的后到{"filed": "test6"}#产生错误,抛弃{"error" : {"root_cause" : [{"type" : "version_conflict_engine_exception","reason" : "[7]: version conflict, required seqNo [22], primary term [1]. current document has seqNo [23] and primary term [1]","index_uuid" : "tdMcqHK5ReOYmOAxPWoqUQ","shard" : "0","index" : "bobotest"}],"type" : "version_conflict_engine_exception","reason" : "[7]: version conflict, required seqNo [22], primary term [1]. current document has seqNo [23] and primary term [1]","index_uuid" : "tdMcqHK5ReOYmOAxPWoqUQ","shard" : "0","index" : "bobotest"},"status" : 409}#重新get if_seq_no和_primary_term的信息。GET /bobotest/_doc/7{"_index" : "bobotest","_type" : "_doc","_id" : "7","_version" : 5,"_seq_no" : 23,"_primary_term" : 1,"found" : true,"_source" : {"filed" : "test4"}}#带上_seq_no=23和_primary_term=1进行修改PUT /bobotest/_doc/7?if_seq_no=23&if_primary_term=1{"filed": "test6"}{"_index" : "bobotest","_type" : "_doc","_id" : "7","_version" : 6,"result" : "updated","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 24,"_primary_term" : 1}
4、external version并发版本控制
https://www.elastic.co/guide/en/elasticsearch/reference/7.1/docs-index_.html#_version_types
在es 7.9版本,index的内部版本并发控制改为_seq_no和_primary_term
但是如果使用external 版本控制,还是使用原先的方式_version &version_type=external
_version 必须>内部_version 的版本号
(1)创建索引PUT /liang/_doc/1{"filed": "test1"}{"_index" : "liang","_type" : "_doc","_id" : "1","_version" : 1,"result" : "created","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 0,"_primary_term" : 1}(2)带入版本进行修改_version 必须>内部_version 的版本号PUT /liang/_doc/1?version=2&version_type=external{"filed": "test2"}{"_index" : "liang","_type" : "_doc","_id" : "1","_version" : 2,"result" : "updated","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 1,"_primary_term" : 1}(3)使用客户端1更新此version=2版本的数据PUT /liang/_doc/1?version=2&version_type=external{"filed": "test2"}{"_index" : "liang","_type" : "_doc","_id" : "1","_version" : 3,"result" : "updated","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 2,"_primary_term" : 1}(4)使用客户端2更新version=2版本的数据(由于两个客户端同时更新,所以版本号一致)PUT /liang/_doc/1?version=2&version_type=external{"filed": "test3"}{"error" : {"root_cause" : [{"type" : "version_conflict_engine_exception","reason" : "[1]: version conflict, current version [3] is higher or equal to the one provided [2]","index_uuid" : "Vs-63nbZT8qDPo2MCJ43xg","shard" : "0","index" : "liang"}],"type" : "version_conflict_engine_exception","reason" : "[1]: version conflict, current version [3] is higher or equal to the one provided [2]","index_uuid" : "Vs-63nbZT8qDPo2MCJ43xg","shard" : "0","index" : "liang"},"status" : 409}(5)出现错误,重新get ,进行更新GET /liang/_doc/1{"_index" : "liang","_type" : "_doc","_id" : "1","_version" : 3,"_seq_no" : 2,"_primary_term" : 1,"found" : true,"_source" : {"filed" : "test3"}}version=4&version_type=external中version必须要比_version大PUT /liang/_doc/1?version=4&version_type=external{"filed": "test3"}{"_index" : "liang","_type" : "_doc","_id" : "1","_version" : 4,"result" : "updated","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 3,"_primary_term" : 1}

