## 银行交易系统（高并发 C++ 架构设计）

### 目标
- 高并发、多线程下安全处理账户的存取款与转账交易。
- 保证数据一致性（余额不丢失、不重复扣减、不出现负数越界）。
- 提供良好的可扩展性（线程池扩展、事务批量处理、异步化）。

### 总体架构
- 线程池（ThreadPool）
  - 固定数量工作线程，阻塞队列提交任务，`submit` 返回 `std::future`。
  - 任务异常安全：在线程内捕获，传播到 future。
- 并发账户模型（Bank）
  - 使用账户级细粒度互斥锁（每个账户一个 `std::mutex`）。
  - 存取款：持有该账户的独占锁；转账：对两个账户“按序加锁”避免死锁。
  - 余额使用 `long long` 存储，所有修改在互斥锁保护下进行。
- 事务模型（Transaction）
  - 三类：Deposit、Withdraw、Transfer。
  - 携带唯一 ID、源/目标账户、金额。
  - 结果（TransactionResult）包含 ID、是否成功、错误信息等。
- 事务处理器（TransactionProcessor）
  - 将事务批量提交到线程池并发执行。
  - 聚合执行结果，保证与输入顺序无关但可按 ID 关联。

### 并发控制与一致性
- 账户级锁粒度：
  - 单账户操作（存/取）：持有单锁，临界区尽量小。
  - 两账户操作（转账）：总是先锁定较小账户 ID，再锁定较大账户 ID，避免死锁。
- 资金校验：
  - 取款与转账需校验余额是否足够；不足则失败并不修改状态。
  - 存款允许任意非负金额（示例中约束金额 > 0）。
- 原子性：
  - 每笔事务在其临界区内要么全部成功，要么失败不改状态。

### 可扩展性考量
- 线程池大小：
  - CPU 密集型任务：≈ CPU 核数。
  - I/O 或混合型：可适当放大（2x~4x）。
- 分区与扩展（如有超大规模账户）：
  - 可按账户 ID 进行分片（Sharding），每片内独立锁。跨片转账可用“两阶段锁”或消息中间件。
- 多机部署（超出本示例范围）：
  - 使用分布式事务或最终一致（事件驱动）。

### 异常与容错
- 线程任务异常被捕获并通过 `std::future` 传播到调用端。
- 对业务失败（余额不足、账户不存在）以业务错误返回，不抛异常。

### 性能权衡
- 账户级锁优点：锁粒度小、冲突少；缺点：转账需双锁。
- 避免使用全局大锁（吞吐低）。
- 不采用 `std::atomic<long long>` 直接更新余额，因为转账需要跨两个账户的复合不变量，必须使用互斥保证一致性。

### 数据校验与账实相符
- 可在批处理前记录总余额 `S0`，统计净现金流 `Δ`（存款+，取款-），最终核对 `S1 == S0 + Δ`。
- 转账对总余额无影响。

### 目录结构（计划）
```
bank_transaction/
  ├─ include/
  │   ├─ thread_pool.hpp
  │   ├─ bank.hpp
  │   ├─ transaction.hpp
  │   └─ transaction_processor.hpp
  ├─ src/
  │   └─ main.cpp
  ├─ v1.0.cpp            # 原始简单实现（单线程示例）
  ├─ CMakeLists.txt
  ├─ README.md
  └─ ARCHITECTURE.md
```

### 测试思路
- 随机生成大量事务（混合存取款与转账），并发执行。
- 统计期望净现金流并校对最终余额总和。
- 在高线程数与高冲突（同一账户热度高）的情况下观察吞吐与延迟。


