没有框架的 HikariCP
HikariCP without Framework
我第一次使用 HikariCP Java 但没有使用任何后端框架或 JPA。
我的项目有以下包结构
----db
----controllers
----views
----models
----handlers
在 db.DBManager.java
中设置了 hikari 数据源:
public class DBManager {
final protected HikariDataSource hikariDS;
protected Connection connection = null;
public DBManager() {
String resourceName = "re/iprocu/coperativeerp/config/db/dbSettings.properties"; // could also be a constant
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Properties props = new Properties();
try(InputStream resourceStream = loader.getResourceAsStream(resourceName)) {
props.load(resourceStream);
} catch (IOException ex) {
Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
}
final HikariConfig hikariConfig = new HikariConfig(props);
//hikariConfig.setConnectionInitSql(absoluteFilePath);
hikariConfig.setMaximumPoolSize(30);
hikariConfig.setMinimumIdle(10);
hikariConfig.setPoolName("TripPool");
hikariConfig.setConnectionTimeout(1000);
hikariConfig.setConnectionTestQuery("SELECT 1");
hikariConfig.setAutoCommit(true);
hikariConfig.setInitializationFailFast(false);
hikariConfig.setLeakDetectionThreshold(2000);
this.hikariDS = new HikariDataSource(hikariConfig);
}
}
在handlers
包中是放置对数据库的查询的地方。
处理程序 类 扩展 DBManager 以获取初始化的 hikari 数据源。
package re.iprocu.coperativeerp.handlers;
public class InventoryHandler extends DBManager{
final static private Logger logger = Logger.getLogger(SupplierHandler.class.getName());
public InventoryHandler(){
super();
}
public int addProductToInventory(Inventory inv){
int key = 0;
PreparedStatement ps = null;
try{
connection = hikariDS.getConnection();
ps = connection.prepareStatement(sql);
ps.executeUpdate();
generatedKeys = ps.getGeneratedKeys();
if (generatedKeys != null && generatedKeys.next()) {
key = generatedKeys.getInt(1);
} else {
System.out.println("No Key");
}
}catch(SQLException e){ e.printStackTrace();}
finally{
if( connection != null ){
try {connection.close();}
catch (SQLException ex) {logger.log(Level.SEVERE, null, ex);}
}
if( ps != null){
try { ps.close();}
catch (SQLException ex) { logger.log(Level.SEVERE, null, ex);}
}
}
return key;
}
}
在 controllers
包中,我定义并初始化了我需要使用的处理程序,并调用相应的方法。
问题是在刷新 ui 或有时第一次加载后,抛出错误 java.sql.SQLTransientConnectionException: TripPool - Connection is not available, request timed out after 1001ms.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
根据我的项目结构,配置 HikariCP 并最大限度地利用它的最佳方法是什么
编辑:
我发现这个 Whosebug Question 它对我有用,但我担心的是解决方案有一个 Double-checked locking
问题在讨论中没有解决,我不知道该怎么做
您的错误消息显示,您的数据库当前打开的连接太多。所以首先你可以查阅你的数据库文档并增加连接限制。或者与您的数据库管理员交谈,如果您有的话。
可能的原因是您为 DBManager
的任何子类的每个新实例创建了新的数据源。使您的 hikariDS
成为静态字段并在静态块中对其进行初始化:
public class DBManager {
public static final HikariDataSource hikariDS;
static {
String resourceName = "re/iprocu/coperativeerp/config/db/dbSettings.properties";
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Properties props = new Properties();
try(InputStream resourceStream = loader.getResourceAsStream(resourceName)) {
props.load(resourceStream);
} catch (IOException ex) {
Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
}
final HikariConfig hikariConfig = new HikariConfig(props);
hikariConfig.setMaximumPoolSize(30);
hikariConfig.setMinimumIdle(10);
hikariConfig.setPoolName("TripPool");
hikariConfig.setConnectionTimeout(1000);
hikariConfig.setConnectionTestQuery("SELECT 1");
hikariConfig.setAutoCommit(true);
hikariConfig.setInitializationFailFast(false);
hikariConfig.setLeakDetectionThreshold(2000);
DBManager.hikariDS = new HikariDataSource(hikariConfig);
}
}
我还删除了 connection
字段。您最好将其存储在方法的局部变量中。
我第一次使用 HikariCP Java 但没有使用任何后端框架或 JPA。
我的项目有以下包结构
----db
----controllers
----views
----models
----handlers
在 db.DBManager.java
中设置了 hikari 数据源:
public class DBManager {
final protected HikariDataSource hikariDS;
protected Connection connection = null;
public DBManager() {
String resourceName = "re/iprocu/coperativeerp/config/db/dbSettings.properties"; // could also be a constant
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Properties props = new Properties();
try(InputStream resourceStream = loader.getResourceAsStream(resourceName)) {
props.load(resourceStream);
} catch (IOException ex) {
Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
}
final HikariConfig hikariConfig = new HikariConfig(props);
//hikariConfig.setConnectionInitSql(absoluteFilePath);
hikariConfig.setMaximumPoolSize(30);
hikariConfig.setMinimumIdle(10);
hikariConfig.setPoolName("TripPool");
hikariConfig.setConnectionTimeout(1000);
hikariConfig.setConnectionTestQuery("SELECT 1");
hikariConfig.setAutoCommit(true);
hikariConfig.setInitializationFailFast(false);
hikariConfig.setLeakDetectionThreshold(2000);
this.hikariDS = new HikariDataSource(hikariConfig);
}
}
在handlers
包中是放置对数据库的查询的地方。
处理程序 类 扩展 DBManager 以获取初始化的 hikari 数据源。
package re.iprocu.coperativeerp.handlers;
public class InventoryHandler extends DBManager{
final static private Logger logger = Logger.getLogger(SupplierHandler.class.getName());
public InventoryHandler(){
super();
}
public int addProductToInventory(Inventory inv){
int key = 0;
PreparedStatement ps = null;
try{
connection = hikariDS.getConnection();
ps = connection.prepareStatement(sql);
ps.executeUpdate();
generatedKeys = ps.getGeneratedKeys();
if (generatedKeys != null && generatedKeys.next()) {
key = generatedKeys.getInt(1);
} else {
System.out.println("No Key");
}
}catch(SQLException e){ e.printStackTrace();}
finally{
if( connection != null ){
try {connection.close();}
catch (SQLException ex) {logger.log(Level.SEVERE, null, ex);}
}
if( ps != null){
try { ps.close();}
catch (SQLException ex) { logger.log(Level.SEVERE, null, ex);}
}
}
return key;
}
}
在 controllers
包中,我定义并初始化了我需要使用的处理程序,并调用相应的方法。
问题是在刷新 ui 或有时第一次加载后,抛出错误 java.sql.SQLTransientConnectionException: TripPool - Connection is not available, request timed out after 1001ms.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
根据我的项目结构,配置 HikariCP 并最大限度地利用它的最佳方法是什么
编辑:
我发现这个 Whosebug Question 它对我有用,但我担心的是解决方案有一个 Double-checked locking
问题在讨论中没有解决,我不知道该怎么做
您的错误消息显示,您的数据库当前打开的连接太多。所以首先你可以查阅你的数据库文档并增加连接限制。或者与您的数据库管理员交谈,如果您有的话。
可能的原因是您为 DBManager
的任何子类的每个新实例创建了新的数据源。使您的 hikariDS
成为静态字段并在静态块中对其进行初始化:
public class DBManager {
public static final HikariDataSource hikariDS;
static {
String resourceName = "re/iprocu/coperativeerp/config/db/dbSettings.properties";
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Properties props = new Properties();
try(InputStream resourceStream = loader.getResourceAsStream(resourceName)) {
props.load(resourceStream);
} catch (IOException ex) {
Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
}
final HikariConfig hikariConfig = new HikariConfig(props);
hikariConfig.setMaximumPoolSize(30);
hikariConfig.setMinimumIdle(10);
hikariConfig.setPoolName("TripPool");
hikariConfig.setConnectionTimeout(1000);
hikariConfig.setConnectionTestQuery("SELECT 1");
hikariConfig.setAutoCommit(true);
hikariConfig.setInitializationFailFast(false);
hikariConfig.setLeakDetectionThreshold(2000);
DBManager.hikariDS = new HikariDataSource(hikariConfig);
}
}
我还删除了 connection
字段。您最好将其存储在方法的局部变量中。