首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JDBC程序數據庫無變化排查:事務提交缺失與參數綁定錯誤雙重檢查

     編輯:程式設計綜合問答

現象描述

代碼邏輯無誤、無異常拋出,但數據庫記錄未更新/插入。

核心檢查清單

檢查點錯誤表現正確做法
自動提交關閉conn.setAutoCommit(false)後未commit()執行完DML必須 `conn.commit()`
PreparedStatement參數索引setString(1, val) 但SQL佔位符從0開始JDBC參數索引**從1開始**
SQL語句拼接字符串拼接導致注入/語法錯誤全程使用 `?` 佔位符 + setXxx()
異常吞噬catch塊只打印堆疊,不回滾、不拋出catch中 `conn.rollback()` 並重新拋出
連接池泄漏連接未歸還導致事務懸掛try-with-resources 自動關閉

標準事務模板


public void transfer(String from, String to, double amount) {
    String sql = "UPDATE account SET balance = balance + ? WHERE name = ?";
    
    try (Connection conn = dataSource.getConnection()) {
        conn.setAutoCommit(false);  // 開啟事務
        
        try (PreparedStatement ps = conn.prepareStatement(sql)) {
            // 扣款
            ps.setDouble(1, -amount);
            ps.setString(2, from);
            ps.executeUpdate();
            
            // 入賬
            ps.setDouble(1, amount);
            ps.setString(2, to);
            ps.executeUpdate();
            
            conn.commit();  // 關鍵:提交事務
        } catch (SQLException e) {
            conn.rollback();  // 回滾
            throw new RuntimeException("轉賬失敗", e);
        }
    } catch (SQLException e) {
        throw new RuntimeException("數據庫連接失敗", e);
    }
}

調試技巧

  1. 開啟JDBC驅動日誌:`java.util.logging.ConsoleHandler.level=FINEST`
  2. 使用P6Spy / log4jdbc 記錄實際執行SQL與參數
  3. 數據庫端開啟通用日誌:MySQL `general_log=ON`,Oracle `AUDIT`
  4. 斷點調試:檢查`executeUpdate()`返回值(受影響行數)

原提問者自查結果

「已找到原因,字符打多了」——通常是SQL語句中多引號、少逗號、或參數順序錯位。

總結

數據庫無變化 90% 是 **事務未提交** 或 **參數綁定錯誤**。「字符打多了」看似小錯,實則是SQL拼接不可控的典型證據。**堅持PreparedStatement + 顯式事務 + try-with-resources**,告別此類低級錯誤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved