新闻详情

新闻详情

首页 / 资讯中心 / 详情

零工日结提现:余额、提现单、事务、幂等,我是这么把这笔“钱“管住的

发布时间:2026/9/26 18:45:00来源:尧图网络
零工日结提现:余额、提现单、事务、幂等,我是这么把这笔“钱“管住的
零工日结提现余额、提现单、事务、幂等我是这么把这笔钱管住的导读xllg 是日结零工系统工人干完活当天就能提现。涉及钱的逻辑我最怕出 bug——多扣一笔、重复到账、提现单和余额对不上哪一样都够喝一壶的。这篇讲讲提现链路是怎么设计的余额账户 提现单 事务 幂等四层一起上。表结构余额和流水分开余额不能只存一个数字还得有流水可追溯。两张表user_wallet存账户余额wallet_flow存每一笔变动CREATETABLEuser_wallet(idBIGINTPRIMARYKEYAUTO_INCREMENT,user_idBIGINTNOTNULLCOMMENT用户ID,balanceDECIMAL(10,2)NOTNULLDEFAULT0.00COMMENT可用余额,frozenDECIMAL(10,2)NOTNULLDEFAULT0.00COMMENT冻结金额提现中的,versionINTNOTNULLDEFAULT0COMMENT乐观锁版本号,update_timeDATETIMEDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,UNIQUEKEYuk_user(user_id))ENGINEInnoDBDEFAULTCHARSETutf8mb4COMMENT用户余额账户;CREATETABLEwallet_flow(idBIGINTPRIMARYKEYAUTO_INCREMENT,user_idBIGINTNOTNULL,typeTINYINTNOTNULLCOMMENT1收入 2支出 3冻结 4解冻,amountDECIMAL(10,2)NOTNULL,balance_afterDECIMAL(10,2)NOTNULLCOMMENT变动后余额,biz_noVARCHAR(64)NOTNULLCOMMENT业务单号幂等键,create_timeDATETIMEDEFAULTCURRENT_TIMESTAMP,UNIQUEKEYuk_biz(biz_no))ENGINEInnoDBDEFAULTCHARSETutf8mb4COMMENT钱包流水;核心设计流水表的 biz_no 唯一索引就是幂等键同一笔提现重复提交第二次插流水直接报唯一键冲突。提现事务先冻结再记账提现逻辑分两步把可用余额冻结生成提现单。两步必须在一个事务里否则出现钱冻了但单子没建就乱了ServicepublicclassWithdrawService{AutowiredprivateWalletMapperwalletMapper;AutowiredprivateWithdrawMapperwithdrawMapper;AutowiredprivateFlowMapperflowMapper;Transactional(rollbackForException.class)publicvoidapplyWithdraw(LonguserId,BigDecimalamount){// 1. 扣减可用余额、增加冻结带乐观锁防止并发intupdatedwalletMapper.freeze(userId,amount);if(updated!1){thrownewBizException(余额不足或账户被并发修改请重试);}// 2. 生成提现单WithdrawordernewWithdraw();order.setUserId(userId);order.setAmount(amount);order.setStatus(0);// 待打款withdrawMapper.insert(order);// 3. 记流水biz_no 唯一重复提交会失败flowMapper.insert(FlowBuilder.build(userId,3,amount,提现冻结));}}walletMapper.freeze的 SQL 是关键一条 UPDATE 同时完成判断和扣减UPDATEuser_walletSETfrozenfrozen#{amount},versionversion1WHEREuser_id#{userId}ANDbalance#{amount}balance #{amount}条件不满足时影响行数为 0Java 侧拿updated ! 1判断天然防住余额不够还提现和并发扣超。踩坑事务方法内部调自己Transactional 失效现象提现接口偶发出现余额扣了但提现单没生成的情况。查库发现 wallet_flow 有冻结流水、user_wallet 余额也减了但 withdraw 表里没有对应记录。排查先看日志报的是NullPointerException——插入提现单前取用户信息时空指针。关键问题是异常抛出来了但余额已经扣了说明事务没回滚。再看代码发现applyWithdraw是被同一个类里的另一个方法handleWithdrawRequest通过this.applyWithdraw()调用的。定位这就是经典的自调用问题——Transactional依赖 Spring 代理this.xxx()是直接调用原始对象的方法代理根本不参与事务注解形同虚设异常自然不会回滚。解决把提现事务方法拆到独立 Service或者通过注入自己的代理调用ServicepublicclassWithdrawService{// 通过 AopContext 拿代理调用自己保证事务生效Transactional(rollbackForException.class)publicvoidapplyWithdraw(LonguserId,BigDecimalamount){// ...冻结 建单 流水}publicvoidhandleWithdrawRequest(LonguserId,BigDecimalamount){// 需要事务的方法必须经过代理((WithdrawService)AopContext.currentProxy()).applyWithdraw(userId,amount);}}改造后测试验证人为制造异常余额、提现单、流水全部回滚三者保持一致。可直接复用的清单余额和流水分表余额是结果、流水是证据对账靠流水扣余额的 SQL 把判断 扣减合到一条 UPDATE影响行数做并发控制提现单用biz_no唯一索引做幂等重复提交直接冲突报错事务方法禁止自调用必须经过 Spring 代理才生效金额一律用DECIMAL禁止 float/double精度问题都是血泪这套提现链路在 xllg 里上线后对账单月月能对上没出过一次金额纠纷。涉及钱的功能宁可多写一层幂等也别赌不会重复提交。项目源码https://gitee.com/gzqkl/xllg
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

层次分析法(AHP)实战指南:从判断矩阵到权重计算的完整Python实现 2026/9/26 20:27:49

层次分析法(AHP)实战指南:从判断矩阵到权重计算的完整Python实现

做评价类项目时,最头疼的不是找不到数据,而是怎么把一堆“感觉”变成能说服别人的“权重”。层次分析法(AHP)这几年帮我处理了不少这类问题,它不需要海量样本,也不需要多复杂的数学模型,核心就一…

阅读更多 →
Flutter鸿蒙设备控制台:cli_tools命令解析与中继总线架构实战 2026/9/26 20:27:49

Flutter鸿蒙设备控制台:cli_tools命令解析与中继总线架构实战

看完这个标题,我第一反应是:这不像一个普通项目,倒像一张“底层适配路线图”。核心线索很清晰——Flutter 三方库、cli_tools、鸿蒙 HarmonyOS(ohos)、命令解析中继总线、设备控制台、隔离层、可视化动效。说白了&…

阅读更多 →
HTTP、Socket、WebSocket、SOAP到底啥区别?理清网络通信层级与选型 2026/9/26 20:27:49

HTTP、Socket、WebSocket、SOAP到底啥区别?理清网络通信层级与选型

后端开发做久了,总会遇到一类提问方式:Http、Socket、WebSocket、WebService(SOAP)到底有什么区别?面试官喜欢问,刚转行的同事也喜欢问。表面上是四个名词,实际上它们处在网络通信的不同层级,混在一起聊永远…

阅读更多 →
HTTP、Socket、WebSocket、WebService对比:协议分层与选型实战指南 2026/9/26 20:27:49

HTTP、Socket、WebSocket、WebService对比:协议分层与选型实战指南

先说个在技术群里看到无数次的问题:“我该用Socket还是WebService?”——这个问题本身问错了,但几乎所有争论都在为这个错题吵。有人甩出“Socket性能好”,有人反驳“WebService跨语言”,其实Socket是操作系统开放的编…

阅读更多 →
第K大元素解法:堆排序与快速选择Java实现及复杂度详解 2026/9/26 20:27:49

第K大元素解法:堆排序与快速选择Java实现及复杂度详解

LeetCode 热题100里有一道几乎每个 Java 后端候选人都绕不开的题:数组中的第K个最大元素。我第一次在面试现场被问到它时,第一反应是Arrays.sort之后取倒数第 k 个,结果被面试官一连串“时间复杂度?能优化吗?数据流场景…

阅读更多 →
伪分布式Hadoop搭建指南:从环境检查到WordCount实战 2026/9/26 20:27:43

伪分布式Hadoop搭建指南:从环境检查到WordCount实战

1. 环境准备:装之前的三个硬性检查开始之前,先把话说透。伪分布式Hadoop测试这个事,说难不难,但环境不对,后面每一步都是坑。我自己带过不少新人,也看过太多人在第一步就栽跟头,所以我先把前置环…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉