修复:强化库存事务并发与日期边界

This commit is contained in:
焦龙言
2026-07-26 13:54:42 +08:00
parent 85905d85ca
commit 6c2a5fa344
5 changed files with 187 additions and 40 deletions
@@ -1,4 +1,4 @@
from sqlalchemy import func, select
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from module_business.entity.do.master_do import BizPallet
@@ -15,7 +15,10 @@ class InventoryDao:
pallet_id: int,
) -> BizPalletInventory | None:
result = await db.execute(
select(BizPalletInventory).where(BizPalletInventory.pallet_id == pallet_id).with_for_update()
select(BizPalletInventory)
.where(BizPalletInventory.pallet_id == pallet_id)
.with_for_update()
.execution_options(populate_existing=True)
)
return result.scalar_one_or_none()
@@ -34,6 +37,7 @@ class InventoryDao:
.where(BizPalletInventory.pallet_id.in_(ordered_ids))
.order_by(BizPalletInventory.pallet_id)
.with_for_update()
.execution_options(populate_existing=True)
)
return sorted(result.scalars().all(), key=lambda inventory: inventory.pallet_id)
@@ -62,6 +66,7 @@ class InventoryDao:
.where(BizPallet.pallet_id.in_(ordered_ids))
.order_by(BizPallet.pallet_id)
.with_for_update()
.execution_options(populate_existing=True)
)
return sorted(result.scalars().all(), key=lambda pallet: pallet.pallet_id)
@@ -89,9 +94,13 @@ class InventoryDao:
) -> BizPalletEvent:
"""在调用方持有库存行锁时,为托盘追加下一序号事件。"""
sequence_result = await db.execute(
select(func.max(BizPalletEvent.event_seq)).where(BizPalletEvent.pallet_id == inventory.pallet_id)
select(BizPalletEvent.event_seq)
.where(BizPalletEvent.pallet_id == inventory.pallet_id)
.order_by(BizPalletEvent.event_seq.desc())
.limit(1)
.with_for_update()
)
last_sequence = sequence_result.scalar_one()
last_sequence = sequence_result.scalar_one_or_none()
event.pallet_id = inventory.pallet_id
event.event_seq = (last_sequence or 0) + 1
db.add(event)
@@ -1,4 +1,4 @@
from datetime import datetime, time
from datetime import datetime, time, timedelta
from typing import Any
from sqlalchemy import ColumnElement, Select, delete, select, update
@@ -45,10 +45,10 @@ class OperationDao:
conditions.append(column >= begin_at)
if end_time:
end_at = datetime.combine(
datetime.strptime(end_time, '%Y-%m-%d').date(),
time(23, 59, 59),
datetime.strptime(end_time, '%Y-%m-%d').date() + timedelta(days=1),
time.min,
)
conditions.append(column <= end_at)
conditions.append(column < end_at)
return conditions
@staticmethod
@@ -74,7 +74,12 @@ class OperationDao:
record_id: int,
*extra_conditions: ColumnElement[bool],
) -> Any | None:
result = await db.execute(select(model).where(id_column == record_id, *extra_conditions).with_for_update())
result = await db.execute(
select(model)
.where(id_column == record_id, *extra_conditions)
.with_for_update()
.execution_options(populate_existing=True)
)
return result.scalar_one_or_none()
@staticmethod
@@ -135,7 +140,7 @@ class OperationDao:
payload = {
column.key: vars(record)[column.key]
for column in model.__table__.columns
if column.key != primary_key and column.key in vars(record)
if column.key not in {primary_key, 'create_by', 'create_time'} and column.key in vars(record)
}
if payload:
await db.execute(update(model).where(id_column == getattr(record, primary_key)).values(**payload))
@@ -370,6 +375,7 @@ class OperationDao:
@classmethod
async def delete_inbound(cls, db: AsyncSession, inbound_id: int) -> None:
await db.execute(delete(BizInboundItem).where(BizInboundItem.inbound_id == inbound_id))
await cls._delete(db, BizInboundOrder, BizInboundOrder.inbound_id, inbound_id)
@classmethod
@@ -520,6 +526,7 @@ class OperationDao:
@classmethod
async def delete_shipment(cls, db: AsyncSession, shipment_id: int) -> None:
await db.execute(delete(BizShipmentItem).where(BizShipmentItem.shipment_id == shipment_id))
await cls._delete(
db,
BizShipmentOrder,