322 lines
7.6 KiB
Markdown
322 lines
7.6 KiB
Markdown
|
|
# 充值审批余额未更新 - 紧急诊断和修复方案
|
|||
|
|
|
|||
|
|
**问题**: 充值审批成功后,用户资金账户余额没有增加
|
|||
|
|
|
|||
|
|
**紧急程度**: 🔴 高危
|
|||
|
|
|
|||
|
|
**时间**: 2026-03-24 11:45
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚨 立即检查清单
|
|||
|
|
|
|||
|
|
### 1. 服务是否重启?(最可能的原因)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 检查服务运行时间
|
|||
|
|
ps -p $(pgrep -f monisuo-1.0.jar) -o lstart,etime
|
|||
|
|
|
|||
|
|
# 如果运行时间早于代码提交时间,说明没有重启
|
|||
|
|
# 代码提交时间: 2026-03-24 11:36
|
|||
|
|
# 如果服务运行时间早于这个时间,必须重启!
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**重启服务**:
|
|||
|
|
```bash
|
|||
|
|
# 停止旧服务
|
|||
|
|
pkill -f "monisuo-1.0.jar"
|
|||
|
|
|
|||
|
|
# 启动新服务
|
|||
|
|
cd ~/Desktop/projects/monisuo
|
|||
|
|
nohup java -jar target/monisuo-1.0.jar > logs/spring.log 2>&1 &
|
|||
|
|
|
|||
|
|
# 查看日志
|
|||
|
|
tail -f logs/spring.log
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. 查看审批日志
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 查找最近的审批日志
|
|||
|
|
grep -A30 "充值审批成功" logs/spring.log | tail -50
|
|||
|
|
|
|||
|
|
# 应该看到:
|
|||
|
|
# ✅ [FundService.approve] 步骤4: 处理充值通过...
|
|||
|
|
# ✅ 审批前余额: 0.00
|
|||
|
|
# ✅ 准备更新账户余额: 100.00
|
|||
|
|
# ✅ 执行 SQL UPDATE (使用 LambdaUpdateWrapper)...
|
|||
|
|
# ✅ 账户更新结果: 1 (1=成功, 0=失败)
|
|||
|
|
# ✅ 验证更新后余额: 100.00
|
|||
|
|
# ✅ [充值审批成功] ...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. 数据库验证
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 1. 查询订单状态
|
|||
|
|
SELECT order_no, user_id, amount, status, approve_time
|
|||
|
|
FROM order_fund
|
|||
|
|
WHERE order_no = '订单号';
|
|||
|
|
|
|||
|
|
-- 2. 查询账户余额(关键!)
|
|||
|
|
SELECT user_id, balance, total_deposit, update_time
|
|||
|
|
FROM account_fund
|
|||
|
|
WHERE user_id = [用户ID];
|
|||
|
|
|
|||
|
|
-- 3. 查询流水记录
|
|||
|
|
SELECT * FROM account_flow
|
|||
|
|
WHERE related_order_no = '订单号'
|
|||
|
|
ORDER BY create_time DESC;
|
|||
|
|
|
|||
|
|
-- 4. 如果余额未更新,手动更新(临时方案)
|
|||
|
|
UPDATE account_fund
|
|||
|
|
SET balance = balance + [充值金额],
|
|||
|
|
total_deposit = total_deposit + [充值金额],
|
|||
|
|
update_time = NOW()
|
|||
|
|
WHERE user_id = [用户ID];
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 问题分析
|
|||
|
|
|
|||
|
|
### 当前代码逻辑(已修复版本)
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// FundService.approve() - 充值审批通过
|
|||
|
|
if (order.getType() == 1 && status == 2) {
|
|||
|
|
// 1. 计算新余额
|
|||
|
|
BigDecimal newBalance = fund.getBalance().add(order.getAmount());
|
|||
|
|
BigDecimal newTotalDeposit = fund.getTotalDeposit().add(order.getAmount());
|
|||
|
|
|
|||
|
|
// 2. 使用 LambdaUpdateWrapper 显式更新
|
|||
|
|
LambdaUpdateWrapper<AccountFund> wrapper = new LambdaUpdateWrapper<>();
|
|||
|
|
wrapper.eq(AccountFund::getId, fund.getId())
|
|||
|
|
.set(AccountFund::getBalance, newBalance)
|
|||
|
|
.set(AccountFund::getTotalDeposit, newTotalDeposit)
|
|||
|
|
.set(AccountFund::getUpdateTime, LocalDateTime.now());
|
|||
|
|
|
|||
|
|
// 3. 执行更新
|
|||
|
|
int updateResult = accountFundMapper.update(null, wrapper);
|
|||
|
|
|
|||
|
|
// 4. 验证更新
|
|||
|
|
if (updateResult <= 0) {
|
|||
|
|
throw new RuntimeException("充值审批更新账户余额失败");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 5. 再次查询验证
|
|||
|
|
AccountFund verifyFund = accountFundMapper.selectById(fund.getId());
|
|||
|
|
if (!verifyFund.getBalance().equals(newBalance)) {
|
|||
|
|
throw new RuntimeException("余额更新失败");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 6. 记录流水
|
|||
|
|
assetService.createFlow(userId, 1, amount, balanceBefore, newBalance, "USDT", orderNo, "充值");
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 可能的问题点
|
|||
|
|
|
|||
|
|
#### 问题1: 服务未重启 ⭐⭐⭐⭐⭐
|
|||
|
|
**症状**: 代码已修改,但服务还在运行旧版本
|
|||
|
|
**原因**: Java 应用需要重启才能加载新代码
|
|||
|
|
**解决**: 重启服务
|
|||
|
|
|
|||
|
|
#### 问题2: 事务回滚
|
|||
|
|
**症状**: 日志显示更新成功,但数据库未变化
|
|||
|
|
**原因**: 事务在后续步骤失败并回滚
|
|||
|
|
**验证**: 查看日志是否有异常
|
|||
|
|
**解决**: 修复后续步骤的错误
|
|||
|
|
|
|||
|
|
#### 问题3: 查询错误账户
|
|||
|
|
**症状**: 更新了账户,但查询的是另一个账户
|
|||
|
|
**原因**: user_id 不匹配
|
|||
|
|
**验证**: 检查订单的 user_id 和账户的 user_id
|
|||
|
|
**解决**: 确保查询条件正确
|
|||
|
|
|
|||
|
|
#### 问题4: MyBatis 缓存
|
|||
|
|
**症状**: 数据库已更新,但查询返回旧数据
|
|||
|
|
**原因**: MyBatis 一级缓存或二级缓存
|
|||
|
|
**解决**: 清除缓存或禁用缓存
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 修复方案
|
|||
|
|
|
|||
|
|
### 方案 A: 立即重启服务(推荐)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ~/Desktop/projects/monisuo
|
|||
|
|
pkill -f "monisuo-1.0.jar"
|
|||
|
|
nohup java -jar target/monisuo-1.0.jar > logs/spring.log 2>&1 &
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**验证**:
|
|||
|
|
1. 执行一次充值审批
|
|||
|
|
2. 查看日志是否有"账户更新结果: 1"
|
|||
|
|
3. 查询数据库确认余额增加
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 方案 B: 添加强制清除缓存
|
|||
|
|
|
|||
|
|
修改 `FundService.approve()`:
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 在方法开始添加
|
|||
|
|
@Autowired
|
|||
|
|
private SqlSession sqlSession;
|
|||
|
|
|
|||
|
|
@Transactional
|
|||
|
|
public void approve(...) {
|
|||
|
|
// 强制清除 MyBatis 缓存
|
|||
|
|
sqlSession.clearCache();
|
|||
|
|
|
|||
|
|
// ... 原有逻辑
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 方案 C: 添加最终验证和重试
|
|||
|
|
|
|||
|
|
在 `FundService.approve()` 方法最后添加:
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 在方法最后添加最终验证
|
|||
|
|
AccountFund finalFund = accountFundMapper.selectById(fund.getId());
|
|||
|
|
System.out.println("[最终验证] 数据库实际余额: " + finalFund.getBalance());
|
|||
|
|
|
|||
|
|
if (!finalFund.getBalance().equals(newBalance)) {
|
|||
|
|
System.err.println("[严重错误] 余额更新失败!");
|
|||
|
|
System.err.println(" - 期望余额: " + newBalance);
|
|||
|
|
System.err.println(" - 实际余额: " + finalFund.getBalance());
|
|||
|
|
|
|||
|
|
// 尝试再次更新
|
|||
|
|
int retryResult = accountFundMapper.update(null, wrapper);
|
|||
|
|
System.out.println("[重试更新] 结果: " + retryResult);
|
|||
|
|
|
|||
|
|
if (retryResult <= 0) {
|
|||
|
|
throw new RuntimeException("余额更新失败,事务将回滚");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 方案 D: 检查事务配置
|
|||
|
|
|
|||
|
|
确认 `SpcCloudApplication.java` 是否有 `@EnableTransactionManagement`:
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@SpringBootApplication
|
|||
|
|
@EnableTransactionManagement // ⭐ 必须有这个
|
|||
|
|
public class SpcCloudApplication {
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 验证脚本
|
|||
|
|
|
|||
|
|
使用我创建的验证脚本:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
chmod +x ~/Desktop/projects/monisuo/verify_balance.sh
|
|||
|
|
./verify_balance.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 执行步骤
|
|||
|
|
|
|||
|
|
### 步骤1: 立即重启服务
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ~/Desktop/projects/monisuo
|
|||
|
|
pkill -f "monisuo-1.0.jar"
|
|||
|
|
nohup java -jar target/monisuo-1.0.jar > logs/spring.log 2>&1 &
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 步骤2: 测试审批
|
|||
|
|
|
|||
|
|
1. 登录管理后台
|
|||
|
|
2. 进入"订单管理" -> "待审批订单"
|
|||
|
|
3. 选择一个充值订单
|
|||
|
|
4. 点击"审批通过"
|
|||
|
|
5. **不要关闭页面**
|
|||
|
|
|
|||
|
|
### 步骤3: 立即查看日志
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
tail -f logs/spring.log | grep -A20 "FundService.approve"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**应该看到**:
|
|||
|
|
```
|
|||
|
|
[FundService.approve] 步骤4: 处理充值通过...
|
|||
|
|
- 审批前余额: 0.00
|
|||
|
|
- 准备更新账户余额: 100.00
|
|||
|
|
- 执行 SQL UPDATE (使用 LambdaUpdateWrapper)...
|
|||
|
|
- 账户更新结果: 1 (1=成功, 0=失败) <-- 必须是 1
|
|||
|
|
- 验证更新后余额: 100.00
|
|||
|
|
[充值审批成功] 订单号: xxx, 充值金额: 100 USDT
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 步骤4: 数据库验证
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 查询订单状态(应该是3)
|
|||
|
|
SELECT order_no, status, approve_time FROM order_fund WHERE order_no = '订单号';
|
|||
|
|
|
|||
|
|
-- 查询账户余额(应该增加了)
|
|||
|
|
SELECT user_id, balance, total_deposit FROM account_fund WHERE user_id = [用户ID];
|
|||
|
|
|
|||
|
|
-- 查询流水记录(应该有记录)
|
|||
|
|
SELECT * FROM account_flow WHERE related_order_no = '订单号';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ❌ 如果问题依然存在
|
|||
|
|
|
|||
|
|
提供以下信息:
|
|||
|
|
|
|||
|
|
1. **服务启动时间**
|
|||
|
|
```bash
|
|||
|
|
ps -p $(pgrep -f monisuo-1.0.jar) -o lstart
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **完整审批日志**
|
|||
|
|
```bash
|
|||
|
|
grep -A50 "审批订单开始" logs/spring.log | tail -60
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **数据库查询结果**
|
|||
|
|
```sql
|
|||
|
|
-- 订单信息
|
|||
|
|
SELECT * FROM order_fund WHERE order_no = '订单号';
|
|||
|
|
|
|||
|
|
-- 账户信息
|
|||
|
|
SELECT * FROM account_fund WHERE user_id = [用户ID];
|
|||
|
|
|
|||
|
|
-- 流水记录
|
|||
|
|
SELECT * FROM account_flow WHERE related_order_no = '订单号';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. **事务日志**
|
|||
|
|
```bash
|
|||
|
|
grep -i "transaction\|rollback\|commit" logs/spring.log | tail -20
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**最后更新**: 2026-03-24 11:45
|
|||
|
|
**状态**: 等待重启服务并测试
|
|||
|
|
**预期修复时间**: 5分钟
|