Я работаю над веб-приложением, в котором отображаю некоторую информацию, с которой пользователь может работать.После принятия мер список должен обновиться и отразить эти изменения на веб-странице.У меня работают все отдельные части, но соединение их вместе вызывает проблемы.
Вот, по сути, код для поиска:
public List<Entry> findEntriesForIdByStatus(Long id, Status status) {
MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("id", id);
if (null == status) {
return template.query(FIND_ALL_ENTRIES_QUERY, paramSource, entryResultSetExtractor);
}
paramSource.addValue("status", status.getCode());
List<Entry> entryWithStatus = springJdbcTemplate.query(FIND_ENTRIES_FOR_STATUS_QUERY,
paramSource,
entryResultSetExtractor);
return equipmentWithStatus;
}
И код обновления:
@Transactional("myTransactionManager")
public void expire(CustomObject customObj) {
Timestamp expirationTime = Timestamp.valueOf(dateTimeFactory.now());
Long id = customObj.getId();
List<Entry> entryList = customObj.getEntryList();
SqlParameterSource[] params = new MapSqlParameterSource[entryList.size()];
for (int i = 0; i < entryList.size(); i++) {
Entry entry = entryList.get(i);
MapSqlParameterSource paramSource = new MapSqlParameterSource("id", id)
.addValue("fieldA", entry.getFieldA())
.addValue("fieldB", entry.getFieldB())
.addValue("expirationTime", expirationTime);
params[i] = paramSource;
}
springJdbcTemplate.batchUpdate(EXPIRE_QUERY, params);
}
Шаблон представляет собой SpringJDBCNamedParameterTemplate, которым управляет Spring Boot, а источник данных является экземпляром com.zaxxer.hikari.HikariDataSource.
Метод поиска вызывается при загрузке страницы и возвращении правильных данных.При запуске метода expire срок действия правильных записей истек, и оба метода выполняются успешно.Первоначально я связывал их во внешнем интерфейсе, используя excludeMap (rxjs / angular 7), но это было противоречиво.Иногда извлечение после истечения возвращалось, как если бы истечение не произошло, а иногда это происходит.Однако, независимо от результата, если я обновлю страницу, результаты будут пустыми, как и ожидалось.Я переключил его на цепочку вызовов на стороне сервера, чтобы посмотреть, поможет ли это вообще, и он начал возвращать результаты, как будто истечение срока не происходило все время, но после обновления страницы это работало как ожидалось.
Вот цепочка на бэкенде:
public @ResponseBody List<Entry> expireEntries(@RequestBody CustomObj customObj) {
entryService.expire(customObj, WebUtil.getCurrentUser());
System.out.println(LocalDateTime.now().toString() + ": about to retrieve");
List<Entry> entries = entryService.findEntriesByStatus(customObj.getId(), Status.NA);
System.out.println(LocalDateTime.now().toString() + ": it's done retrieving");
return equips;
}
Сервисы в значительной степени просто вызывают DAO без особого перерыва между ними.Выходные данные журнала аналогичны приведенным ниже:
не работает
2019-09-19T13: 33: 50,998: собирается удалить
2019-09-19T13: 33: 51.050: завершено удаление
2019-09-19T13: 33: 51.246: готово к извлечению
13: 33: 51.465 [http-nio-8080-exec-3] INFO EntryDAO - запрос для родителя 27 со статусом= NA вернул 364 и занял 219 миллисекунд
13: 33: 51.466 [http-nio-8080-exec-3] INFO EntryService - запрос для родителя 27 и статус NA вернул 364
2019-09-19T13: 33:51.466: завершено получение
обработано
2019-09-19T13: 38: 13.752: собирается удалить
2019-09-19T13: 38: 13.798:Завершено удаление
2019-09-19T13: 38: 14.112: собирается получить
13: 38: 14.120 [http-nio-8080-exec-5] INFO EntryDAO - запрос для родителя 27 с возвращенным статусом = NA0 и заняло 8 миллисекунд
13: 38: 14.120 [http-nio-8080-exec-5] INFO EntryService - запрос для родителя 27 и статус NA вернул 0
2019-09-19T13: 38: 14.120: этозавершено получение
Они относятся к тому моменту, когда цепочка была на переднем конце, но после перехода к бэкэнду, то же самое, только с «Это сделано, удаление» и «почти извлекается» ближе во времени, обычно в течение миллисекунды илидва.Похоже, что добавление двухсекундного сна между обновлением и поиском устранит проблему.Я попытался заблокировать строки для обновления и сделать методы транзакционными с помощью аннотации Spring @Transactional, но ни один из них не помог.
Насколько я могу судить, похоже, что пакетное обновление запускается, но метод Javaвозвращает до фактического завершения обновления в базе данных.Поэтому, когда запрос извлечения выполняется, он получает данные перед обновлением.Кто-нибудь может подтвердить, что это такое поведение, и если это так, есть ли способ исправить это, не взламывая его с помощью Thread.sleep?
EDIT: Вот определение компонента для диспетчера транзакций.
@Bean(name = "myDbProperties")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.mydb")
public DataSourceProperties dbProperties() {
return new DataSourceProperties();
}
@Primary
@Bean(name = "myDataSource")
@ConfigurationProperties(prefix = "spring.datasource.mydb.configuration")
public DataSource dataSource(@Qualifier("myDbProperties") DataSourceProperties dbProperties) {
return dbProperties.initializeDataSourceBuilder().build();
}
@Bean
@Primary
@Qualifier("myTransactionManager")
public PlatformTransactionManager loadauthTransactionManager(
@Qualifier("myDataSource") DataSource datasource) {
return new DataSourceTransactionManager(datasource);
}