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

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

Optimistic lock in Spring data for ElasticSearch doesn't work

问题

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

示例:

ElasticSearchConfig:

@Configuration
public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {

    @Override
    public RestHighLevelClient elasticsearchClient() {
        String host = "localhost"; int port = 9200;
        try {
            System.out.println("ElasticSearch host: " + host + ", port: " + port);
            ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                    .connectedTo(host + ":" + port)
                    .build();
            return RestClients.create(clientConfiguration).rest();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

实体:

@Document(indexName = Ent.INDEX_ENTITY, type = "_doc")
public class Ent {
    public static final String INDEX_ENTITY = "entity";
    @Id
    public String id;
    public String data;
    public Ent(String data) {
        this.data = data;
    }
    @JsonIgnore
    public long version;
    public Ent setData(String arg) {
        this.data = arg;
        return this;
    }
}

测试应用:

@SpringBootApplication
public class App {

    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    protected ElasticsearchOperations elasticsearchOperations;

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @Autowired
    EntRepository entRepository;

    @PostConstruct
    public void testUpdate() throws Exception {
        Ent ent = entRepository.save(new Ent("some data"));
        for (int i = 0; i < 3; i++) {
            update(ent.setData("data-"+System.currentTimeMillis()));
            System.out.println("version = " + ent.version);
        }
    }

    public Ent update(Ent ent) throws JsonProcessingException {
        UpdateQuery updateQuery = new UpdateQuery();
        updateQuery.setIndexName(Ent.INDEX_ENTITY);
        updateQuery.setId(ent.id);
        updateQuery.setType("_doc");
        updateQuery.setUpdateRequest(
                new UpdateRequest()
                        .version(1)
                        .versionType(VersionType.EXTERNAL_GTE) // doesn't affect actually...
                        .doc(objectMapper.writeValueAsString(ent), XContentType.JSON)
        );
        UpdateResponse updateResponse = elasticsearchOperations.update(updateQuery);
        ent.version = updateResponse.getVersion();
        return ent;
    }

}

所以,我得到输出:

version = 2
version = 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:

@Configuration
public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {

    @Override
    public RestHighLevelClient elasticsearchClient() {
        String host = &quot;localhost&quot;; int port = 9200;
        try {
            System.out.println(&quot;ElasticSearch host: &quot; + host + &quot;, port: &quot; + port);
            ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                    .connectedTo(host + &quot;:&quot; + port)
                    .build();
            return  RestClients.create(clientConfiguration).rest();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Entity:

@Document(indexName = Ent.INDEX_ENTITY, type = &quot;_doc&quot;)
public class Ent {
    public static final String INDEX_ENTITY = &quot;entity&quot;;
    @Id
    public String id;
    public String data;
    public Ent(String data) {
        this.data = data;
    }
    @JsonIgnore
    public long version;
    public Ent setData(String arg) {
        this.data = arg;
        return this;
    }
}

Test App:

@SpringBootApplication
public class App {

@Autowired
ObjectMapper objectMapper;
@Autowired
protected ElasticsearchOperations elasticsearchOperations;

public static void main(String[] args) {
    SpringApplication.run(App.class, args);
}

@Autowired
EntRepository entRepository;

@PostConstruct
public void testUpdate() throws Exception {
    Ent ent = entRepository.save(new Ent(&quot;some data&quot;));
    for (int i = 0; i &lt; 3; i++) {
        update(ent.setData(&quot;data-&quot;+System.currentTimeMillis()));
        System.out.println(&quot;version = &quot; + ent.version);
    }
}

public Ent update(Ent ent) throws JsonProcessingException {
    UpdateQuery updateQuery = new UpdateQuery();
    updateQuery.setIndexName(Ent.INDEX_ENTITY);
    updateQuery.setId(ent.id);
    updateQuery.setType(&quot;_doc&quot;);
    updateQuery.setUpdateRequest(
            new UpdateRequest()
                    .version(1)
                    .versionType(VersionType.EXTERNAL_GTE) // doesn&#39;t affect actually...
                    .doc(objectMapper.writeValueAsString(ent), XContentType.JSON)
    );
    UpdateResponse updateResponse = elasticsearchOperations.update(updateQuery);
    ent.version = updateResponse.getVersion();
    return ent;
}

}

so, i'm getting output:

version = 2
version = 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:

确定