英文:
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 = "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);
}
}
}
Entity:
@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;
}
}
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("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;
}
}
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) ?
专注分享java语言的经验与见解,让所有开发者获益!
评论