在Spring Data for ElasticSearch中,乐观锁机制不起作用。

huangapple 未分类评论53阅读模式
英文:

Optimistic lock in Spring data for ElasticSearch doesn't work

问题

Spring Data for ElasticSearch 是否支持通过 @Version 进行文档版本控制?
看起来不支持。如果不支持,如何正确实现?

示例:

ElasticSearchConfig:

  1. @Configuration
  2. public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {
  3. @Override
  4. public RestHighLevelClient elasticsearchClient() {
  5. String host = "localhost"; int port = 9200;
  6. try {
  7. System.out.println("ElasticSearch host: " + host + ", port: " + port);
  8. ClientConfiguration clientConfiguration = ClientConfiguration.builder()
  9. .connectedTo(host + ":" + port)
  10. .build();
  11. return RestClients.create(clientConfiguration).rest();
  12. } catch (Exception e) {
  13. throw new RuntimeException(e);
  14. }
  15. }
  16. }

实体:

  1. @Document(indexName = Ent.INDEX_ENTITY, type = "_doc")
  2. public class Ent {
  3. public static final String INDEX_ENTITY = "entity";
  4. @Id
  5. public String id;
  6. public String data;
  7. public Ent(String data) {
  8. this.data = data;
  9. }
  10. @JsonIgnore
  11. public long version;
  12. public Ent setData(String arg) {
  13. this.data = arg;
  14. return this;
  15. }
  16. }

测试应用:

  1. @SpringBootApplication
  2. public class App {
  3. @Autowired
  4. ObjectMapper objectMapper;
  5. @Autowired
  6. protected ElasticsearchOperations elasticsearchOperations;
  7. public static void main(String[] args) {
  8. SpringApplication.run(App.class, args);
  9. }
  10. @Autowired
  11. EntRepository entRepository;
  12. @PostConstruct
  13. public void testUpdate() throws Exception {
  14. Ent ent = entRepository.save(new Ent("some data"));
  15. for (int i = 0; i < 3; i++) {
  16. update(ent.setData("data-"+System.currentTimeMillis()));
  17. System.out.println("version = " + ent.version);
  18. }
  19. }
  20. public Ent update(Ent ent) throws JsonProcessingException {
  21. UpdateQuery updateQuery = new UpdateQuery();
  22. updateQuery.setIndexName(Ent.INDEX_ENTITY);
  23. updateQuery.setId(ent.id);
  24. updateQuery.setType("_doc");
  25. updateQuery.setUpdateRequest(
  26. new UpdateRequest()
  27. .version(1)
  28. .versionType(VersionType.EXTERNAL_GTE) // doesn't affect actually...
  29. .doc(objectMapper.writeValueAsString(ent), XContentType.JSON)
  30. );
  31. UpdateResponse updateResponse = elasticsearchOperations.update(updateQuery);
  32. ent.version = updateResponse.getVersion();
  33. return ent;
  34. }
  35. }

所以,我得到输出:

  1. version = 2
  2. version = 3
  3. version = 4

但是即使我设置了 new UpdateRequest().version(1),它从未失败。
那么如何做到如果版本不如预期(或低于预期)则使其失败?

英文:

Does Spring Data for ElasticSearch support document versioning via @Version?
Seems no. If doesn't support, how to do it properly?

Example:

ElasticSearchConfig:

  1. @Configuration
  2. public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {
  3. @Override
  4. public RestHighLevelClient elasticsearchClient() {
  5. String host = &quot;localhost&quot;; int port = 9200;
  6. try {
  7. System.out.println(&quot;ElasticSearch host: &quot; + host + &quot;, port: &quot; + port);
  8. ClientConfiguration clientConfiguration = ClientConfiguration.builder()
  9. .connectedTo(host + &quot;:&quot; + port)
  10. .build();
  11. return RestClients.create(clientConfiguration).rest();
  12. } catch (Exception e) {
  13. throw new RuntimeException(e);
  14. }
  15. }
  16. }

Entity:

  1. @Document(indexName = Ent.INDEX_ENTITY, type = &quot;_doc&quot;)
  2. public class Ent {
  3. public static final String INDEX_ENTITY = &quot;entity&quot;;
  4. @Id
  5. public String id;
  6. public String data;
  7. public Ent(String data) {
  8. this.data = data;
  9. }
  10. @JsonIgnore
  11. public long version;
  12. public Ent setData(String arg) {
  13. this.data = arg;
  14. return this;
  15. }
  16. }

Test App:

  1. @SpringBootApplication
  2. public class App {
  3. @Autowired
  4. ObjectMapper objectMapper;
  5. @Autowired
  6. protected ElasticsearchOperations elasticsearchOperations;
  7. public static void main(String[] args) {
  8. SpringApplication.run(App.class, args);
  9. }
  10. @Autowired
  11. EntRepository entRepository;
  12. @PostConstruct
  13. public void testUpdate() throws Exception {
  14. Ent ent = entRepository.save(new Ent(&quot;some data&quot;));
  15. for (int i = 0; i &lt; 3; i++) {
  16. update(ent.setData(&quot;data-&quot;+System.currentTimeMillis()));
  17. System.out.println(&quot;version = &quot; + ent.version);
  18. }
  19. }
  20. public Ent update(Ent ent) throws JsonProcessingException {
  21. UpdateQuery updateQuery = new UpdateQuery();
  22. updateQuery.setIndexName(Ent.INDEX_ENTITY);
  23. updateQuery.setId(ent.id);
  24. updateQuery.setType(&quot;_doc&quot;);
  25. updateQuery.setUpdateRequest(
  26. new UpdateRequest()
  27. .version(1)
  28. .versionType(VersionType.EXTERNAL_GTE) // doesn&#39;t affect actually...
  29. .doc(objectMapper.writeValueAsString(ent), XContentType.JSON)
  30. );
  31. UpdateResponse updateResponse = elasticsearchOperations.update(updateQuery);
  32. ent.version = updateResponse.getVersion();
  33. return ent;
  34. }
  35. }

so, i'm getting output:

  1. version = 2
  2. version = 3
  3. version = 4

but it never fails although I set
new UpdateRequest().version(1)

So how to do so that it fails if version is not as expected (or lower than expected) ?

huangapple
  • 本文由 发表于 2020年4月7日 18:06:07
  • 转载请务必保留本文链接:https://java.coder-hub.com/61077507.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定