現象
數據庫記錄已更新(如通過 Navicat 直接修改),但 Hibernate 查詢仍返回舊數據,重啟應用後恢復正常。
根因
- Hibernate 默認連接池(
ConnectionProvider)未正確處理連接驗證,導致從池中獲取的連接持有**舊快照/事務隔離視圖**。
- MySQL 默認
REPEATABLE READ 隔離級別 + 連接池連接複用 = 可重複讀視圖不刷新。
解決方案:替換為 C3P0 連接池
在 hibernate.cfg.xml 中添加:
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">120</property>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="c3p0.testConnectionOnCheckout">true</property>
<property name="c3p0.idleConnectionTestPeriod">18000</property>
<property name="c3p0.maxIdleTime">25000</property>
關鍵配置解析
| 參數 | 含義 | 建議值 |
| testConnectionOnCheckout | 從池取連接時驗證有效性 | true(核心,防脏連接) |
| idleConnectionTestPeriod | 空閒連接定期驗證間隔(秒) | 18000 (5小時) |
| maxIdleTime | 空閒連接最大存活(秒) | 25000 (7小時) |
| idle_test_period | C3P0 內部空閒檢測(秒) | 120 (2分鐘) |
更優選:HikariCP(現代標準)
C3P0 維護緩慢,生產環境強烈建議遷移至 HikariCP:
<property name="hibernate.connection.provider_class">com.zaxxer.hikari.hibernate.HikariConnectionProvider</property>
<property name="hibernate.hikari.dataSourceClassName">com.mysql.cj.jdbc.MysqlDataSource</property>
<property name="hibernate.hikari.dataSource.url">jdbc:mysql://localhost:3306/db?useSSL=false</property>
<property name="hibernate.hikari.dataSource.user">user</property>
<property name="hibernate.hikari.dataSource.password">pass</property>
<property name="hibernate.hikari.maximumPoolSize">20</property>
<property name="hibernate.hikari.minimumIdle">5</property>
<property name="hibernate.hikari.connectionTestQuery">SELECT 1</property>
<property name="hibernate.hikari.idleTimeout">300000</property>
<property name="hibernate.hikari.maxLifetime">1800000</property>
補充:事務隔離級別設置
若業務允許 READ COMMITTED,可在連接 URL 添加:
jdbc:mysql://localhost:3306/db?useSSL=false&sessionVariables=tx_isolation='READ-COMMITTED'
或 Hibernate 配置:
<property name="hibernate.connection.isolation">2</property>
驗證方法
- 啟動應用,查詢某記錄。
- Navicat 直接更新該記錄。
- 應用再次查詢,應返回新值(無需重啟)。
- 上一篇文章: MySQL LOAD DATA INFILE 高效導入全解析:語法詳解、參數避坑與千萬級實戰優化
- 下一篇文章: MySQL 數據目錄遷移後啟動失敗:InnoDB 臨時文件創建失敗與 ib_logfile 損壞排查實錄
Copyright ©
程式碼之家 All Rights Reserved