Как настроить оптимистическую блокировку для перекрытия даты и времени?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как настроить оптимистическую блокировку для перекрытия даты и времени?

Сообщение Anonymous »

Я пытаюсь создать систему бронирования, в которой пользователи могут забронировать место в определенном месте на определенный период времени. Проблема, с которой я столкнулся, заключается в том, что две записи происходят одновременно и перекрываются в течение периода времени.
Если периоды времени одинаковы, я решил это, добавив уникальное ограничение (я использую жидкость): Но если они происходят точно в одно и то же время и перекрываются, они оба сохраняются в базе данных.
Например:
р>

Код: Выделить всё

{
"userId": 7,
"startTime": "2024-07-04T12:00:00",
"endTime": "2024-07-04T14:00:00",
"location": {
"id": 2
}
},
{
"userId": 8,
"startTime": "2024-07-04T12:00:00",
"endTime": "2024-07-04T14:00:00",
"location": {
"id": 2
}
},
{
"userId": 9,
"startTime": "2024-07-04T13:00:00",
"endTime": "2024-07-04T15:00:00",
"location": {
"id": 2
}
}
До добавления ограничения все они были добавлены в базу данных, но после ограничения добавляются только 2 из них, поскольку существует точная копия.

Код: Выделить всё

{
"userId": 7,
"startTime": "2024-07-04T12:00:00",
"endTime": "2024-07-04T14:00:00",
"location": {
"id": 2
}
},
{
"userId": 8,
"startTime": "2024-07-04T12:00:00",
"endTime": "2024-07-04T14:00:00",
"location": {
"id": 2
}
}
Но

Код: Выделить всё

{
"userId": 8,
"startTime": "2024-07-04T12:00:00",
"endTime": "2024-07-04T14:00:00",
"location": {
"id": 2
}
},
{
"userId": 9,
"startTime": "2024-07-04T13:00:00",
"endTime": "2024-07-04T15:00:00",
"location": {
"id": 2
}
}
по-прежнему добавляются в базу данных, поскольку даже если они не совпадают по времени, они все равно перекрывают друг друга.
Как я перед добавлением проверяю вот это:

Код: Выделить всё

@Transactional
public BookingDTO createBooking(Booking booking) {
Location location = locationRepository.findById(booking.getLocation().getId())
.orElseThrow(() -> new IllegalArgumentException("Location not found"));

boolean bookingEndsBeforeItStarts = booking.getEndTime().isBefore(booking.getStartTime());
if (bookingEndsBeforeItStarts) throw new IllegalArgumentException("Booking can't end before it starts.");

if (bookingRepository.existsOverlappingBooking(location.getId(), booking.getStartTime())) {
throw new IllegalArgumentException("Overlapping booking exists for the given location and time.");
}

try {
booking.setLocation(location);
Booking savedBooking = bookingRepository.save(booking);
return BookingMapper.toDTO(savedBooking);
} catch (OptimisticLockException ex) {
throw new IllegalStateException("Optimistic locking failure occurred", ex);
}
}
Проблема в том, что они создаются одновременно с прохождением перекрывающейся проверки, поскольку ни одного из них еще нет в базе данных.
У меня есть попробовал сделать что-то подобное в классе репозитория:

Код: Выделить всё

@Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
Booking save(Booking booking);
Но я подозреваю, что это не работает, поскольку идентификатор пользователя и идентификатор бронирования различаются. Что я могу добавить, так это то, что в базе данных версия всегда равна 0.

Код: Выделить всё

Entity
@Table(name = "booking")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Booking {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "user_id", nullable = false)
private Long userId;

@ManyToOne
@JoinColumn(name = "location_id", nullable = false)
private Location location;

@Column(name = "start_time", nullable = false)
private LocalDateTime startTime;

@Column(name = "end_time", nullable = false)
private LocalDateTime endTime;

@Version
@Column(nullable = false)
private Long version;
}
Аналогично, простое добавление версии, как утверждается в некоторых руководствах, по-прежнему не работает.
Мой вопрос: как я могу настроить это, чтобы оно работало с оптимистическая блокировка.
Мой репозиторий: https://github.com/VMM-MMV/BookingService

Подробнее здесь: https://stackoverflow.com/questions/787 ... g-datetime
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»