首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 計數器教學(五):JDBC 版——MySQL 持久化支援集群

     編輯:Java 相關知識

本篇將計數器持久化層升級為 MySQL 資料庫,利用資料庫行級鎖與事務天然解決集群環境下的併發安全與資料共享問題,代碼採用截圖形式避免格式亂碼。

資料表結構

CREATE TABLE counter (
    id INT PRIMARY KEY AUTO_INCREMENT,
    count_value BIGINT NOT NULL DEFAULT 0,
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
INSERT INTO counter (count_value) VALUES (0);

JDBC 版核心邏輯(截圖代碼文字化)

JDBC 版計數器代碼截圖

<%@ page import="java.sql.*,javax.sql.*" %>
<%@ page import="javax.naming.*" %>
<% 
    // 從 JNDI 取得連接池 DataSource(生產環境最佳實踐)
    InitialContext ctx = new InitialContext();
    DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/counterDB");
    
    long count = 0;
    try (Connection conn = ds.getConnection()) {
        conn.setAutoCommit(false); // 開啟事務
        try (PreparedStatement psLock = conn.prepareStatement(
                "SELECT count_value FROM counter WHERE id = 1 FOR UPDATE")) {
            // SELECT ... FOR UPDATE 獲取行鎖,阻塞其他事務直到提交
            try (ResultSet rs = psLock.executeQuery()) {
                if (rs.next()) count = rs.getLong("count_value");
            }
        }
        count++;
        try (PreparedStatement psUpd = conn.prepareStatement(
                "UPDATE counter SET count_value = ? WHERE id = 1")) {
            psUpd.setLong(1, count);
            psUpd.executeUpdate();
        }
        conn.commit(); // 釋放鎖
    } catch (Exception e) {
        e.printStackTrace();
    }
%>
當前訪問次數:<%= count %>

關鍵技術點

  1. JNDI DataSource:不硬編碼連接參數,由 Tomcat 管理連接池,支援生產環境調優。
  2. SELECT ... FOR UPDATE:InnoDB 行鎖,確保同一時間只有一個事務能讀取並更新該行,天然解決分散式併發。
  3. 事務邊界:setAutoCommit(false) → 查詢+更新 → commit(),原子性保證。
  4. try-with-resources:JDK 7+ 自動關閉 Connection/Statement/ResultSet,無洩漏。
  5. BIGINT:支援超大訪問量(922京),無溢位風險。

Tomcat context.xml 配置 DataSource

<Resource name="jdbc/counterDB" auth="Container" type="javax.sql.DataSource"
    maxTotal="20" maxIdle="10" maxWaitMillis="-1"
    username="root" password="123456"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/test?useSSL=false&characterEncoding=UTF-8"/>

優缺點總結

優點缺點
集群多節點天然共享、強一致性每次訪問需資料庫往返,延遲較高
資料庫備份/遷移/審計完善高併發下資料庫連接池成瓶頸
支援複雜查詢(按日期、IP 統計)需額外維護 MySQL 服務

優化方向

  • 引入 Redis 做熱點計數緩存,定時落地 MySQL。
  • 使用 資料庫連接池(HikariCP/Druid)替換 Tomcat 內建池。
  • 採用 JavaBean/Service 層 分離業務邏輯,下一篇將示範。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved