fix(planting-service): improve outbox event confirmation accuracy
- markAsConfirmed now uses aggregateId + eventType for precise matching - Prevents accidentally confirming multiple events for the same order - EventAckController passes eventType to markAsConfirmed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8de7a668f0
commit
ba5b6141a3
|
|
@ -53,8 +53,11 @@ export class EventAckController {
|
|||
|
||||
try {
|
||||
if (message.success) {
|
||||
// 标记事件为已确认
|
||||
const confirmed = await this.outboxRepository.markAsConfirmed(message.eventId);
|
||||
// 标记事件为已确认(使用 eventId + eventType 精确匹配)
|
||||
const confirmed = await this.outboxRepository.markAsConfirmed(
|
||||
message.eventId,
|
||||
message.eventType,
|
||||
);
|
||||
|
||||
if (confirmed) {
|
||||
this.logger.log(
|
||||
|
|
@ -62,7 +65,7 @@ export class EventAckController {
|
|||
);
|
||||
} else {
|
||||
this.logger.warn(
|
||||
`[ACK] Event ${message.eventId} not found or already confirmed`,
|
||||
`[ACK] Event ${message.eventId} (${message.eventType}) not found or already confirmed`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -145,25 +145,32 @@ export class OutboxRepository {
|
|||
/**
|
||||
* 标记事件为已确认(消费方已成功处理)
|
||||
* B方案:收到消费方确认后调用
|
||||
* 使用 aggregateId + eventType 组合精确匹配,避免误确认同一订单的其他事件
|
||||
*/
|
||||
async markAsConfirmed(eventId: string): Promise<boolean> {
|
||||
// 通过 aggregateId + eventType 查找事件
|
||||
async markAsConfirmed(eventId: string, eventType?: string): Promise<boolean> {
|
||||
const whereClause: Prisma.OutboxEventWhereInput = {
|
||||
aggregateId: eventId,
|
||||
status: OutboxStatus.SENT,
|
||||
};
|
||||
|
||||
// 如果提供了 eventType,则精确匹配
|
||||
if (eventType) {
|
||||
whereClause.eventType = eventType;
|
||||
}
|
||||
|
||||
const result = await this.prisma.outboxEvent.updateMany({
|
||||
where: {
|
||||
aggregateId: eventId,
|
||||
status: OutboxStatus.SENT,
|
||||
},
|
||||
where: whereClause,
|
||||
data: {
|
||||
status: OutboxStatus.CONFIRMED,
|
||||
},
|
||||
});
|
||||
|
||||
if (result.count > 0) {
|
||||
this.logger.log(`[OUTBOX] ✓ Event ${eventId} confirmed by consumer`);
|
||||
this.logger.log(`[OUTBOX] ✓ Event ${eventId} (${eventType || 'all types'}) confirmed by consumer`);
|
||||
return true;
|
||||
}
|
||||
|
||||
this.logger.warn(`[OUTBOX] Event ${eventId} not found or not in SENT status`);
|
||||
this.logger.warn(`[OUTBOX] Event ${eventId} (${eventType || 'any'}) not found or not in SENT status`);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue