Задание
У нас есть ученики и учитель. Как только учитель обновлен (например, мягко удален), мы хотим назначить учеников. Прежде чем они были назначены на учителя. Как мне это сделать?
Я обновляю учителя и отправляю сообщение TeacherUpdatedMessage
. Затем у меня есть потребитель, который принимает сообщения и обновляет студентов.
Наш технический стек
Java, Spring Data Mongodb, MongoDB, архитектура микро-сервисов. Мы также реализовали оптимистическую блокировку c.
Вопрос
Когда я транслирую несколько студентов, может случиться так, что во время потока t1 userEntiy извлекается из базы данных в момент t2 он обновляется в транзакции извне. Следовательно, это поле версии будет увеличено. Тогда в момент t3 наш findAndModify
метод, который вызывает mongoTmplate
.doFindAndReplace()
, потерпит неудачу (поскольку он не нашел документ с заданным идентификатором и версией).
Как мне правильно с этим обращаться?
Наш код
TeacherUpdatedConsumer
@Consumer // Consumer asynchornnous message that the teacher had been already changed
class TeacherUpdatedConsumer {
public void consume(final TeacherUpdatedMessage techerMessage) {
switch (teacherMessage.getEventType()) {
// Similar to other cases.
// In my case removed means it is marked as removed - soft-removal.
case REMOVED:
// Un-assign students from the teacher.
studentService.unassignedStudentsFromTeacher(teacherMessage.getPayload().getId());
// break;
// Next code...
}
}
}
StudentService
class StudentService {
@Transactional
public void unassignedStudentsFromTeacher(final ObjectId teacherId) {
try (Stream<Student> students = studentRepository.streamAllByTeacherIdAndRemovedFalse(teacherId)) {
studentRepository.findAndModify(student, buildQueryDocumentToSetTeacherIdNull());
}
}
}
StudentRepository
использует пружину MongoTemplate
class StudentReository {
Student findAndModify(Student student, Document query) {
mongoTemplate.doFindAndReplace(convertStudentToDocument(student), query);
}
}