实时征收的两阶段同步:先内存后Oracle 实时征收缴费到账的两阶段同步——先内存后Oracle文章目录实时征收缴费到账的两阶段同步——先内存后Oracle一、问题二、两步走三、为什么不用消息队列四、内存库的作用五、同步状态机六、对账兜底七、总结银行说扣款成功只要半秒。但社保核心入库可能要一秒。中间加一层内存库秒变毫秒。一、问题社保缴费的实时征收链路群众在手机或终端上点缴费 → 银行扣款 → 社保系统记账。银行扣款是实时的。但社保系统的 Oracle 入库不一定够快——写缴费记录、更新账户、更新征收状态几张大表的事务提交可能要几百毫秒。几百人在同一秒缴费Oracle 的 IO 就顶不住了。解决方案银行扣款后先写内存库秒级响应再异步同步到 Oracle。二、两步走银行系统 │ ▼ 缴费到账交易 │ ▼ 社保引用服务器 → 写缴费信息到内存数据库 → 成功写入 │ └→ 返回缴费成功给银行半秒不到 异步线程下一秒触发 │ ▼ 查询内存库中未同步的缴费信息 │ ▼ 逐条写入 Oracle缴费记录、到账信息 │ ▼ 更新内存库同步状态 → 标记已同步三、为什么不用消息队列标准做法是银行→Kafka→消费者→Oracle。这套方案的开发量搭建 Kafka 集群写生产者、消费者处理消息丢失、重复消费监控积压这个场景的吞吐量不需要 Kafka。几千人一天缴费峰值每秒十几个。内存库 定时轮询代码量是 Kafka 方案的十分之一。不是所有异步都需要消息队列。量级小、容忍秒级延迟的场景轮询够了。四、内存库的作用内存库不是 Redis。是社保系统自带的内存数据库——一个常驻进程的数据结构响应在微秒级。三个作用缓冲挡住银行的实时请求不让并发压在 Oracle 上去重同一笔交易重复来内存库里已存在的直接返回已处理兜底Oracle 挂了内存库继续收等 Oracle 恢复后批量补写五、同步状态机每笔缴费在内存库里有三个状态待同步 → 同步中 → 已同步 │ │ └─────┬───┘ 失败 → 重试 → 超过N次 → 人工处理伪代码实现// 接收银行缴费反馈实时入口 function 缴费到账(银行交易号, 金额, 人员ID): // 先写内存库 if MemDB.exists(银行交易号): return 已处理 // 去重 record {交易号,金额,人员ID,状态待同步,时间NOW()} MemDB.insert(record) return 缴费成功 // 半秒内返回 // 异步同步线程每30秒执行一次 function 同步到Oracle(): records MemDB.query(状态待同步) for rec in records: MemDB.update(rec.交易号, 状态同步中) try: Oracle.beginTransaction() Oracle.execute(INSERT INTO 缴费记录 ..., rec) Oracle.execute(UPDATE 账户 SET 余额余额? WHERE 人员ID?, rec.金额, rec.人员ID) Oracle.commit() MemDB.update(rec.交易号, 状态已同步) catch Exception as e: Oracle.rollback() rec.重试次数 1 if rec.重试次数 10: MemDB.update(rec.交易号, 状态同步失败-需人工, 错误e.message) else: MemDB.update(rec.交易号, 状态待同步) // 等30秒后重试 // 对账兜底每天凌晨执行 function 日终对账(): bankRecords 解析银行对账文件(d:/recon/bank_20250101.txt) siRecords Oracle.query(SELECT * FROM 缴费记录 WHERE 日期TODAY) memRecords MemDB.queryAll() for bank in bankRecords: si siRecords.find(交易号bank.交易号) if si is None: // 银行扣了、社保没记 → 补记 Oracle.insert(bank) elif si.金额 ! bank.金额: // 金额不一致 → 人工对 alert(对账差异: bank.交易号) for si in siRecords: bank bankRecords.find(交易号si.交易号) if bank is None: // 社保记了、银行没扣 → 冲正 Oracle.update(DELETE FROM 缴费记录 WHERE 交易号?, si.交易号)六、对账兜底银行每天发对账文件过来。系统跑批比对银行扣了、社保没记 → 补记以银行为准社保记了、银行没扣 → 冲正以银行为准两边都有、金额不一致 → 人工对对账是最后一道防线。前面的内存库、异步同步都是为了快。但对账不为快为准。七、总结实时征收的三层设计层作用延迟银行发起扣款实时内存库缓冲 快速响应微秒级Oracle持久化 业务查询秒级异步不是高并发架构是务实架构。量级不需要 Kafka就轮询。对账能兜底就不在实时链路上加过多校验。做政务系统最怕的是用高并发方案解决低并发问题。Kafka 是好的但如果你的峰值就每秒十几个内存库 轮询 对账兜底是最少出事的方案。