У меня есть два http-запроса, которые почти одновременно приходят на мой весенний загрузочный сервер, и оба они должны обновить одну и ту же сущность в базе данных. Первый запрос обновляет ход выполнения задачи, которую выполняет клиент:
fun updateProgress(workUnitId: Int, progress: Double): HttpResponse<Boolean> {
val optionalWorkUnit = workUnitDAO.findById(workUnitId)
return if (optionalWorkUnit.isPresent) {
val workUnit = optionalWorkUnit.get()
workUnit.progress = progress
workUnitDAO.save(workUnit)
logger.info("updating progress ${workUnit.progress}... ${workUnit.status}")
HttpResponse(true)
} else {
HttpResponse(false)
}
}
А второй записывает результат, возвращаемый клиентом обработки:
fun recordResult(workUnitId: Int, result: String): HttpResponse<Boolean> {
val optionalWorkUnit = workUnitDAO.findById(workUnitId)
return if (optionalWorkUnit.isPresent) {
val workUnit = optionalWorkUnit.get()
workUnit.result = result
workUnit.finishDate = Date()
workUnit.status = Status.FINISHED
workUnit.progress = 2.0 // changed from 1.0 to 2.0 to help noticing changes in the db
workUnitDAO.save(workUnit)
logger.info("result recorder ${workUnit.status}")
HttpResponse(true)
} else {
HttpResponse(false)
}
}
Проблема заключается в том, что если первый запрос, который должен быть обработан, записывает результат, затем следующий, который обновляет объект чтения прогресса, так как он никогда не изменялся первым запросом (состояние, сохраненное первым, завершается, но второй читает IN_PROGRESS):
2020-04-29 18:30:15.595 INFO 16368 --- [nio-8082-exec-2] p.p.server.service.WorkUnitService : result recorder FINISHED
2020-04-29 18:30:15.595 INFO 16368 --- [nio-8082-exec-3] p.p.server.service.WorkUnitService : updating progress 1.0... IN_PROGRESS
Мой сервис помечен @ Transactional
@Service
@Transactional
class WorkUnitService {
DAO:
interface WorkUnitDAO : JpaRepository<WorkUnit, Int> {
Я попытался изменить методы репозитория save () на saveAndFlu sh (), но это не помогло .
Удаление изменения объекта из метода updateProgress предотвращает это (несмотря на тот факт, что объект все еще сохраняется):
fun updateProgress(workUnitId: Int, progress: Double): HttpResponse<Boolean> {
val optionalWorkUnit = workUnitDAO.findById(workUnitId)
return if (optionalWorkUnit.isPresent) {
val workUnit = optionalWorkUnit.get()
//workUnit.progress = progress //removing this stops overwritting values from recordResult
workUnitDAO.save(workUnit)
logger.info("updating progress ${workUnit.progress}... ${workUnit.status}")
HttpResponse(true)
} else {
HttpResponse(false)
}
}
Настройки:
spring:
datasource:
url: jdbc:mysql://*******:9099/master?useUnicode=true&useLegacyDatetimeCode=false&serverTimezone=UTC
I пробовал аннотировать все с помощью @Transactional, пробовал CrudRepository, ничего не помогло.
Spring boot version: 2.2.4.RELEASE
Я хотел бы эти методы не переопределять друг друга. Я застрял с этим уже несколько часов.
Там что-то я пропустил или сделал не так?