You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java银行应用中数据库用户余额更新失败问题排查求助

问题分析与解决方案

我一眼就看到几个关键问题导致你的数据库余额没更新,咱们一个个拆解:

1. PreparedStatement初始化错误

你创建第二个PreparedStatement时,错把查询语句的query当成了更新语句的query2:

PreparedStatement stmt2 = con.prepareStatement(query); // 这里应该用query2!

这就导致你执行的还是查询操作,根本没触发数据库更新,余额自然不会变。

2. SQL语句拼接存在语法错误

你的更新SQL拼接后会变成这种错误格式:

UPDATE accsSET Balance = 1000WHERE AccountNumber =654321

注意看:accs和SET之间、更新金额和WHERE之间都没有空格,数据库解析时会直接报错,根本不会执行更新逻辑。

3. 额外建议:避免SQL注入,改用参数占位符

你现在直接把账号、金额拼进SQL的写法,不仅容易出语法错误,还存在SQL注入风险。最好用PreparedStatement的?占位符来传递参数,既安全又规范。

修正后的完整代码

public void deposit() {
    System.out.println("How much money do u want to deposit?");
    int val = sc.nextInt();
    
    // 用try-with-resources自动关闭资源,避免内存泄漏
    try (Connection con = DriverManager.getConnection(url, username, password)) {
        // 1. 查询当前余额,用占位符传递账号
        String query = "SELECT Balance FROM accounts.accs WHERE AccountNumber = ?";
        try (PreparedStatement stmt = con.prepareStatement(query)) {
            stmt.setInt(1, 654321); // 给第一个占位符赋值
            try (ResultSet rs = stmt.executeQuery()) {
                // 账号唯一,用if判断即可,无需while循环
                if (rs.next()) {
                    int balance = rs.getInt("Balance");
                    int updatedBalance = balance + val;
                    System.out.println("The updated balance is " + updatedBalance);

                    // 2. 更新余额,同样用占位符传参
                    String query2 = "UPDATE accounts.accs SET Balance = ? WHERE AccountNumber = ?";
                    try (PreparedStatement stmt2 = con.prepareStatement(query2)) {
                        stmt2.setInt(1, updatedBalance);
                        stmt2.setInt(2, 654321);
                        int affectedRows = stmt2.executeUpdate();
                        
                        if (affectedRows > 0) {
                            System.out.println("余额更新成功!");
                            con.commit(); // 若设置了手动提交则需要,默认自动提交可省略
                        } else {
                            System.out.println("未找到对应账号,更新失败");
                        }
                    }
                } else {
                    System.out.println("未找到账号654321的记录");
                }
            }
        }
    } catch (SQLException e) {
        e.printStackTrace(); // 打印异常信息,方便快速排查问题
    }
}

额外注意事项

  • Connection默认是自动提交模式,若你没设置con.setAutoCommit(false),con.commit()可以直接省略;如果开启了手动提交,必须调用commit()才能让更新生效。
  • 一定要捕获并打印SQLException,之前的SQL语法错误其实会在控制台输出日志,只是你没处理异常所以没看到。
  • try-with-resources语法能自动关闭Connection、PreparedStatement、ResultSet这些资源,避免手动关闭遗漏导致的内存泄漏。

内容的提问来源于stack exchange,提问作者yassoplaya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:16:17