Make copy operation atomic with explicit transaction handling
- Wrapped copy operation in try/except with explicit rollback - Added comments explaining atomicity - Ensures all-or-nothing behavior for copying to multiple dates
This commit is contained in:
parent
c24597edb4
commit
1a478f7583
1 changed files with 32 additions and 25 deletions
|
|
@ -160,34 +160,41 @@ async def copy_availability(
|
||||||
detail=f"No availability found for source date {request.source_date}",
|
detail=f"No availability found for source date {request.source_date}",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Copy to each target date
|
# Copy to each target date within a single atomic transaction
|
||||||
|
# All deletes and inserts happen before commit, ensuring atomicity
|
||||||
copied_days: list[AvailabilityDay] = []
|
copied_days: list[AvailabilityDay] = []
|
||||||
for target_date in request.target_dates:
|
try:
|
||||||
if target_date == request.source_date:
|
for target_date in request.target_dates:
|
||||||
continue # Skip copying to self
|
if target_date == request.source_date:
|
||||||
|
continue # Skip copying to self
|
||||||
# Delete existing availability for target date
|
|
||||||
await db.execute(
|
# Delete existing availability for target date
|
||||||
delete(Availability).where(Availability.date == target_date)
|
await db.execute(
|
||||||
)
|
delete(Availability).where(Availability.date == target_date)
|
||||||
|
|
||||||
# Copy slots
|
|
||||||
target_slots: list[TimeSlot] = []
|
|
||||||
for source_slot in source_slots:
|
|
||||||
new_availability = Availability(
|
|
||||||
date=target_date,
|
|
||||||
start_time=source_slot.start_time,
|
|
||||||
end_time=source_slot.end_time,
|
|
||||||
)
|
)
|
||||||
db.add(new_availability)
|
|
||||||
target_slots.append(TimeSlot(
|
# Copy slots
|
||||||
start_time=source_slot.start_time,
|
target_slots: list[TimeSlot] = []
|
||||||
end_time=source_slot.end_time,
|
for source_slot in source_slots:
|
||||||
))
|
new_availability = Availability(
|
||||||
|
date=target_date,
|
||||||
|
start_time=source_slot.start_time,
|
||||||
|
end_time=source_slot.end_time,
|
||||||
|
)
|
||||||
|
db.add(new_availability)
|
||||||
|
target_slots.append(TimeSlot(
|
||||||
|
start_time=source_slot.start_time,
|
||||||
|
end_time=source_slot.end_time,
|
||||||
|
))
|
||||||
|
|
||||||
|
copied_days.append(AvailabilityDay(date=target_date, slots=target_slots))
|
||||||
|
|
||||||
copied_days.append(AvailabilityDay(date=target_date, slots=target_slots))
|
# Commit all changes atomically
|
||||||
|
await db.commit()
|
||||||
await db.commit()
|
except Exception:
|
||||||
|
# Rollback on any error to maintain atomicity
|
||||||
|
await db.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
return AvailabilityResponse(days=copied_days)
|
return AvailabilityResponse(days=copied_days)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue