Я пытаюсь понять, почему приведенный ниже фрагмент кода не работает должным образом.
У меня уже есть customer
с id=1234 and name=A1
.Я создаю 2 вызываемые задачи и прошу их выполнить transnational update
метод.
Обе транзакции выполняются вместе (так как я ввел 1 секунду задержки после чтения копии клиента из базы данных, как показано в коде) и прочитал оригинального клиента с помощью id=1234 and name=A1
Один пытается update name from A1->A2
и другие попытки update name from A1->A3
Я ожидал, что по крайней мере 1 транзакция вызовет исключение конфликта / устаревших данных при фиксации, но в обоих случаях оба успешно завершатся.
Не могли бы вы помочь мне понять это?Что ж?Я что-то упускаю концептуально?
Main.java
@Autowired
CustomerService service;
// Update address from A1 to A2
Callable<String> t1 = new Callable<String>() {
@Override
public String call() throws Exception {
service.updateCustomer("1234", "A2");
return "T1 Done";
}
};
// Update address from A1 to A3
Callable<String> t2 = new Callable<String>() {
@Override
public String call() throws Exception {
service.updateCustomer("1234", "A3");
return "T2 Done";
}
};
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.invokeAll((Collection) Arrays.asList(t1, t2));
CustomerService.java
@Transactional
public void updateCustomer(String customerId, String customerName) {
try {
Optional<Customer> currentCopyHandle = repo.findById(customerId);
Customer currentCopy = currentCopyHandle.get();
Thread.sleep(1000);
ObjectMapper mapper = new ObjectMapper();
String customerDetails = currentCopy.getDetails();
ObjectNode writableDetails = (ObjectNode) mapper.readTree(customerDetails);
writableDetails.put("name", customerName);
currentCopy.setDetails(mapper.writeValueAsString(writableDetails));
repo.save(currentCopy);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Редактировать-1 Customer.java
Это POJO, совместимый с Oracle 12c, где поле с именем details
помечено как @Lob
, а таблица oracle12c имеет ограничение json
@Entity
public class Customer {
@Id
@javax.persistence.Id
private String cid;
@Lob
private String details;
public Customer() {
}
@PersistenceConstructor
public Customer(String cid, String details) {
super();
this.cid = cid;
this.details = details;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
До того, как я начал это упражнениеЯ сделал ниже деятельности.
String json = "{ \"cid\" : \"1234\", \"name\" : \"A1\", \"address\" : \"India\"}";
service.saveCustomer1(new Customer("1234", json));