【问题标题】:Abstract factory pattern and HikariCP抽象工厂模式和 HikariCP
【发布时间】:2023-03-30 14:33:01
【问题描述】:

我目前正在使用池连接(Hikari)和抽象工厂模式在 Java 中实现我的 MySQL 查询,如下所示:

MySqlFactoryDAO.java

public class MySqlFactoryDAO extends FactoryDAO {

   private static HikariDataSource connPool_;

   public static Connection createConnection() throws SQLException {

      if (connPool_ == null) {
         // Load database configuration
         PropertiesFile props = FactoryConfig.getConfig().getDatabaseProperties();

         connPool_ = new HikariDataSource();
         connPool_.setJdbcUrl(props.getString(Params.DB_URL,""));
         connPool_.setUsername(props.getString(Params.DB_USER,"root"));
         connPool_.setPassword(props.getString(Params.DB_PASSWORD,"root"));
      }
      return connPool_.getConnection();
   }

   //-------------------------------------------------------------------------

   public ProductDAO getProductDAO() {
      return new ProductMySQLFactoryDAO();
   }
}

ProductMySQLFactoryDAO.java

public class ProductMySQLFactoryDAO implements ProductDAO {

   public int insertProduct(String name) {  
      ...
      Connection conn = MySqlFactoryDAO.createConnection();
      ...
   }    
}

我想知道这段代码是否是线程安全的,我认为在coonPool_ 的初始化时存在问题。我在*中读过诸如“Initialization-on-demand_holder_idiom”之类的东西,但我不确定。有没有人有更好的实现来解决这个问题或只是一个更好的新的?

【问题讨论】:

    标签: java mysql design-patterns jdbc hikaricp


    【解决方案1】:

    不,它不是线程安全的。两个线程可能同时调用createConnection(),都将池视为null,并且都创建一个新的DataSource。

    方法需要同步。或者池必须在类初始化时创建:

    private static final HikariDataSource DATA_SOURCE = createDataSource();
    

    您的 connPool_ 字段也应该是私有的。

    【讨论】:

    • 是的,应该是私有的,我复制错了。我想过一个同步的方法,但它认为这里的同步会大大降低性能。