在分布式系统中,银行转账使用 TCC(Try-Confirm-Cancel) 模式时,涉及到多个服务的协作。每个服务需要对其相关资源进行事务管理,以确保转账的一致性与可靠性。不同服务之间的数据结构和表设计至关重要,尤其是如何记录每个阶段的状态、事务的关联等。
以下是银行转账中涉及的 TCC 模式下,不同服务的表结构设计,假设有以下服务:
- 账户服务:负责账户资金的冻结、解冻、扣款和恢复。
- 支付服务:负责资金的实际转账操作。
- 通知服务:负责通知用户转账结果。
1. 账户服务:冻结与解冻账户资金
账户服务的核心功能是管理账户的资金状态,尤其是在 Try 阶段冻结资金,在 Confirm 阶段扣款,在 Cancel 阶段解冻资金。
表结构设计:account_transactions
| 字段名 | 类型 | 描述 |
|---|---|---|
transaction_id | VARCHAR(64) | 事务ID,唯一标识一次银行转账事务 |
account_id | VARCHAR(64) | 账户ID,标识该资金归属于哪个账户 |
amount | DECIMAL(20,2) | 事务金额,表示冻结或扣除的金额 |
status | ENUM | 事务状态(PENDING,COMMITTED,CANCELLED) |
freeze_status | BOOLEAN | 冻结状态,标识是否已冻结资金 |
created_at | TIMESTAMP | 创建时间,标记事务的初始时间 |
updated_at | TIMESTAMP | 更新时间,标记事务状态变更的时间 |
service_name | VARCHAR(64) | 服务名称,标记是哪个服务在处理此操作(如支付服务等) |
action | ENUM | 当前操作类型(TRY,CONFIRM,CANCEL) |
- Try 阶段:在账户服务中,当请求冻结资金时,会插入一条记录,并将状态设置为
PENDING,并且freeze_status设置为TRUE,表示资金已被冻结。 - Confirm 阶段:如果转账成功,账户服务会将
status更新为COMMITTED,表示资金已经成功扣除。 - Cancel 阶段:如果转账失败,账户服务将
status更新为CANCELLED,并解冻资金,freeze_status更新为FALSE。
示例记录:
| TRANSACTION_ID | ACCOUNT_ID | AMOUNT | STATUS | FREEZE_STATUS | CREATED_AT | UPDATED_AT | SERVICE_NAME | ACTION |
|---|---|---|---|---|---|---|---|---|
| txn_123456 | acc_001 | 1000.00 | PENDING | TRUE | 2024-12-02 10:00:00 | 2024-12-02 10:10:00 | Payment | TRY |
| txn_123456 | acc_001 | 1000.00 | COMMITTED | TRUE | 2024-12-02 10:00:00 | 2024-12-02 10:30:00 | Payment | CONFIRM |
2. 支付服务:处理资金转账操作
支付服务的核心任务是执行资金的实际转账操作,它需要协调多个服务之间的事务,确保资金的流动。支付服务需要记录每笔转账的 Try、Confirm 和 Cancel 阶段的执行情况。
表结构设计:payment_transactions
| 字段名 | 类型 | 描述 |
|---|---|---|
transaction_id | VARCHAR(64) | 事务ID,唯一标识一次银行转账事务 |
from_account_id | VARCHAR(64) | 付款账户ID,标识资金来源账户 |
to_account_id | VARCHAR(64) | 收款账户ID,标识资金目标账户 |
amount | DECIMAL(20,2) | 转账金额 |
status | ENUM | 事务状态(PENDING,COMMITTED,CANCELLED) |
created_at | TIMESTAMP | 创建时间 |
updated_at | TIMESTAMP | 更新时间 |
action | ENUM | 当前操作类型(TRY,CONFIRM,CANCEL) |
payment_method | VARCHAR(64) | 支付方式(如银行转账、信用卡等) |
- Try 阶段:支付服务记录转账的初始请求,将状态设置为
PENDING,并执行转账验证操作。 - Confirm 阶段:在资金冻结确认后,支付服务完成实际的资金转移,将状态设置为
COMMITTED。 - Cancel 阶段:在转账过程中出现异常时,支付服务会将状态更新为
CANCELLED,并撤销相关操作。
示例记录:
| TRANSACTION_ID | FROM_ACCOUNT_ID | TO_ACCOUNT_ID | AMOUNT | STATUS | CREATED_AT | UPDATED_AT | ACTION |
|---|---|---|---|---|---|---|---|
| txn_123456 | acc_001 | acc_002 | 1000.00 | PENDING | 2024-12-02 10:00:00 | 2024-12-02 10:10:00 | TRY |
| txn_123456 | acc_001 | acc_002 | 1000.00 | COMMITTED | 2024-12-02 10:00:00 | 2024-12-02 10:30:00 | CONFIRM |
3. 通知服务:发送转账通知
通知服务的职责是根据转账的不同状态(成功、失败等),向用户发送相应的通知。
表结构设计:notifications
| 字段名 | 类型 | 描述 |
|---|---|---|
notification_id | VARCHAR(64) | 通知ID,唯一标识一次通知 |
transaction_id | VARCHAR(64) | 事务ID,关联支付事务 |
user_id | VARCHAR(64) | 用户ID,标识哪个用户需要接收通知 |
message | TEXT | 通知内容,描述转账成功或失败的情况 |
status | ENUM | 通知状态(SENT,FAILED) |
created_at | TIMESTAMP | 创建时间 |
updated_at | TIMESTAMP | 更新时间 |
- Try 阶段:通知服务一般不会在 Try 阶段介入,但可以根据情况发送预通知。
- Confirm 阶段:当转账完成时,通知服务会向用户发送成功通知,
status为SENT。 - Cancel 阶段:如果转账取消,通知服务会向用户发送失败通知,
status为FAILED。
示例记录:
| NOTIFICATION_ID | TRANSACTION_ID | USER_ID | MESSAGE | STATUS | CREATED_AT | UPDATED_AT |
|---|---|---|---|---|---|---|
| notif_123456 | txn_123456 | user_001 | "转账成功,已完成1000元支付" | SENT | 2024-12-02 10:30:00 | 2024-12-02 10:30:00 |
| notif_123457 | txn_123456 | user_001 | "转账失败,1000元支付未完成" | FAILED | 2024-12-02 10:30:00 | 2024-12-02 10:30:00 |
总结
在银行转账过程中使用 TCC 模式时,各个服务(账户服务、支付服务和通知服务)都需要设计相应的表结构来记录事务状态、操作类型(TRY、CONFIRM、CANCEL)以及资源的冻结、解冻、扣款等操作。通过这些表结构,系统能够在分布式环境下保持数据一致性,并确保跨服务的事务协调。