|
|
@@ -118,8 +118,19 @@ class ContractRepository:
|
|
|
stmt = ContractDocument.__table__.update().where(ContractDocument.id == document_id).values(**values)
|
|
|
await self.db.execute(stmt)
|
|
|
|
|
|
+ async def lock_bundle(self, bundle_id: int) -> None:
|
|
|
+ # 行级锁:串行化同一合同包的并发回调,避免 recalc 读到旧快照把"已签署"覆盖回"未签署"
|
|
|
+ await self.db.execute(
|
|
|
+ select(ContractBundle.id).where(ContractBundle.id == bundle_id).with_for_update()
|
|
|
+ )
|
|
|
+
|
|
|
async def recalc_bundle_status(self, bundle_id: int) -> str:
|
|
|
- stmt = select(ContractDocument.status).where(ContractDocument.bundle_id == bundle_id, ContractDocument.delete_flag == 0)
|
|
|
+ # with_for_update 强制当前读,确保读到其它已提交回调写入的最新文档状态
|
|
|
+ stmt = (
|
|
|
+ select(ContractDocument.status)
|
|
|
+ .where(ContractDocument.bundle_id == bundle_id, ContractDocument.delete_flag == 0)
|
|
|
+ .with_for_update()
|
|
|
+ )
|
|
|
result = await self.db.execute(stmt)
|
|
|
statuses = [row[0] for row in result.fetchall()]
|
|
|
if not statuses:
|