You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

事件溯源(Event Sourcing):如何建模不同事件间的关联关系?

Event Sourcing in Banking: Event Correlation for Deposits & Transfers

Great question—this is a common, critical point of confusion when starting with Event Sourcing, especially in financial domains where auditability, traceability, and consistency are non-negotiable. Let’s break this down step by step.

Short answer: Yes, absolutely.

Including a reference to the deposit.created event’s UUID (or better yet, a dedicated depositId that identifies the Deposit entity) in the account.deposited event is essential for three key reasons:

  • Auditability: Financial systems require a clear paper trail. If someone later asks, "Why was $100 added to account X?", you need to trace that change back to the original deposit initiation event.
  • Consistency Validation: When replaying events to rebuild state, you can verify that every account.deposited has a corresponding deposit.created event (and vice versa), catching any orphaned or invalid events that could corrupt account balances.
  • Avoid Duplication: If events are ever reprocessed (e.g., due to a system glitch), the depositId lets you skip duplicate account.deposited events tied to the same deposit.

Example Event Structures:

  • deposit.created:
    {
      "eventId": "deposit-evt-123",
      "type": "deposit.created",
      "depositId": "deposit-456",
      "accountId": "acc-789",
      "amount": 100.00,
      "timestamp": "2024-05-20T14:30:00Z"
    }
    
  • account.deposited:
    {
      "eventId": "acc-evt-001",
      "type": "account.deposited",
      "accountId": "acc-789",
      "amount": 100.00,
      "depositId": "deposit-456",
      "causationId": "deposit-evt-123", // Directly links to the triggering event
      "timestamp": "2024-05-20T14:30:01Z"
    }
    

Note: Using causationId to reference the direct parent event (here, deposit.created) is a standard Event Sourcing pattern for tracking event lineage.

2. Transfer Scenario: Event Correlation Best Practices

Transfers are more complex because they involve two accounts (debit and credit) and a central Transfer entity. The goal is to tie all related events to a single transfer context so you can trace the entire flow from initiation to completion (or failure).

When executing a bank.transfer command, you’ll typically generate a sequence of events like this, all linked by a shared transferId:

  • transfer.initiated: Marks the start of the transfer. Includes transferId, fromAccountId, toAccountId, amount, and any metadata (e.g., user reference).
  • account.withdrawn: Records the debit from the source account. Includes accountId, amount, transferId, and causationId pointing to transfer.initiated.
  • account.deposited: Records the credit to the target account. Includes accountId, amount, transferId, and causationId pointing to transfer.initiated.
  • transfer.completed: Confirms the transfer is fully processed. Includes transferId and references to the account.withdrawn and account.deposited event IDs for full traceability.

Handling Failure Scenarios:

If the transfer fails (e.g., insufficient funds in the source account), you’d generate:

  • transfer.failed: Includes transferId, reason, and causationId pointing to transfer.initiated.
  • account.refunded (if funds were temporarily withdrawn but need to be reversed): Links back to the transferId and the original account.withdrawn event.

Key Pattern: Correlation IDs

For end-to-end traceability across multiple events, use two standard fields:

  • correlationId: A single ID that ties all events in a business process together (e.g., all events from a single transfer command). This is useful for debugging or auditing entire workflows.
  • causationId: The ID of the event that directly triggered the current event (e.g., account.withdrawn’s causation ID is transfer.initiated’s event ID). This tracks the direct lineage of events.

Final Takeaway

In financial Event Sourcing systems, event correlation isn’t just a nice-to-have—it’s a requirement. Linking events via IDs ensures you can audit every transaction, validate state consistency during replay, and debug issues quickly. For both deposits and transfers, always tie related events together using dedicated entity IDs (like depositId or transferId) and lineage fields (causation/correlation IDs).

内容的提问来源于stack exchange,提问作者Calvin Lau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:42:58