0
点赞
收藏
分享

微信扫一扫

Hikari 连接池的复用行为及connection-init-sql初始化sql使用场景


给connection设置了sql_log_bin=0后,将connection归还给hikari,sql_log_bin=0还生效吗?
答案是:不会安全生效,如果直接把 Connection 归还给 Hikari 连接池,sql_log_bin=0 可能会影响下一个使用该连接的 SQL,本文来详细探讨一下:

1️⃣ Hikari 连接池的行为

  1. Hikari 使用 连接池复用,从池中取出的 Connection 可能之前已经被其他线程使用过。
  2. sql_log_binMySQL 会话级变量,属于该连接的状态。
  3. 如果你在方法里执行 SET sql_log_bin=0,然后归还连接:
  • 连接池不会自动重置 sql_log_bin
  • 下一个线程从池中取到这个连接时仍然可能是 0,导致本应写入 binlog 的操作也不会写。

2️⃣ 正确做法

为了保证 连接池安全,必须在使用完成后 立即恢复 sql_log_bin=1,或者在 Hikari 层做初始化:

方法 A:方法执行前后手动恢复

try (Statement stmt = conn.createStatement()) {
    stmt.execute("SET sql_log_bin=0"); // 执行 SQL 不写 binlog
}

// 执行原方法...

try (Statement stmt = conn.createStatement()) {
    stmt.execute("SET sql_log_bin=1"); // 恢复
}

这种方式是我们前面 AOP 实现的方式,保证连接在归还前已经恢复。

方法 B:Hikari 初始化 SQL

Hikari 支持配置 每次取连接时执行的初始化 SQL,确保归还连接状态安全:

spring:
  datasource:
    hikari:
      connection-init-sql: SET sql_log_bin=1

  • 每次从连接池获取连接时,Hikari 会执行 SET sql_log_bin=1,保证默认状态正确。
  • 然后我们在方法里临时执行 SET sql_log_bin=0,方法结束归还前恢复即可。

3️⃣ 小结

  • 直接归还连接,不恢复 sql_log_bin 是不安全的
  • 必须在方法结束前恢复为 1
  • 最稳妥方式:
  1. Hikari 配置 connection-init-sql=SET sql_log_bin=1
  2. AOP 或拦截器临时设置 0 并在 finally 块恢复

这样就可以同时满足 多数据源 + 连接池安全 + binlog 控制


举报

相关推荐

0 条评论