如何正确使用ExecutorService与数据库池连接?

时间:2016-05-09 18:11:46

标签: java multithreading executorservice

我有一个项目,我从文件中读取数据,在数据库中执行一些SQL,并将数据写入数据库。其中一个文件输入字段有25-50个不同的参数(产品属性的值),我必须在将数据写入文件之前进行查询。这是我的过程中最慢的部分 - 所以我认为尝试使用多个线程来实现它是一件好事。

我需要为每个属性值运行一个select语句,如果该值尚不存在,则创建一个新值。创建涉及简单地将SQL和插入语句写入批处理 - 在处理给定产品的所有数据之后,批处理将作为数据库事务的一部分提交。

我有一个AttributeLoader类来处理所有产品属性 - 包括解析传入的属性信息,查找属性的ID然后查找值的id - 并创建一个新的属性值和id如果没有存在。

我还有一个FindAttrValByIdentifier类,它是可运行的类,用于检索属性值(如果它已经存在)。我的计划是利用ExecutorService运行大约20个执行select查询的线程 - 每个线程将传递一个数据库连接以用于查询数据库。当我运行它 - 它似乎处理一个传入线然后挂起。所以,在某个地方,我似乎有一些东西挂在等待状态。下面是我的代码的框架。有谁看到我出轨的地方?它可能是多个地方,因为我不是Java Guru - 特别是涉及到多个线程时。我试图将代码缩减到适用的行 - 所以如果我剪得太多,请告诉我。

//my control class (SpeedLoader)opens the connection pool 
public class SpeedLoader {

private static void initializeConnectionPool() throws PropertyVetoException          {
    cpds = new ComboPooledDataSource();
    cpds.setDriverClass( DB_DRIVER ); //loads the jdbc driver            
    cpds.setJdbcUrl( DB_CONNECTION );
    cpds.setUser(DB_USER);                                  
    cpds.setPassword(DB_PASSWORD); 

 // the settings below are optional -- c3p0 can work with defaults
    cpds.setMinPoolSize(5);                                     
    cpds.setAcquireIncrement(5);
    cpds.setMaxPoolSize(25);
    cpds.setMaxStatements(25);
}
public static synchronized Connection getConnection() throws SQLException {
    return cpds.getConnection();
}

class AttributeLoader {     //this class loads attribute data - and is a single instance that is used throughout the complete load process

AttributeLoader(Connection conn, String filePath, String fileTimestamp) throws Exception {
        dbConnection = conn;
        initialize(filePath, fileTimestamp);
}
public static void  processAttributesForPN(String productPN, long productId) throws Exception{

   List<Future<Long>> future=new ArrayList<Future<Long>>();
   List<FindAttrValIdByIdentifier> callList = new ArrayList<FindAttrValIdByIdentifier>();
   for(Map.Entry<Key, Long> entry : attrValIdCache.entrySet()){  // get values for existing keys
        FindAttrValIdByIdentifier getValId = new FindAttrValIdByIdentifier(entry.getKey().attrId, entry.getKey().identifier);
        callList.add(getValId);
   }
    future=executor.invokeAll(callList);

    // process results 
}
private static void initialize(String filePath, String fileTimestamp) throws Exception {
    try {
        attributeDataFileReader =  new FileReader(filePath+"/"+fileTimestamp+".CatentryAttribute.csv");
        attributeBufferedReader = new BufferedReader(attributeDataFileReader);

    //other stuff
    executor  = (ThreadPoolExecutor) Executors.newFixedThreadPool(20);

public static void close() throws IOException, SQLException{// close is not called until all file processing completes

    // other stuff
    FindAttrValIdByIdentifier.close();
    executor.shutdown();
    while (!executor.isTerminated()) {
    }


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.Callable;

public class FindAttrValIdByIdentifier implements Callable<Long> {

long  attrId;
String identifier;
static Connection pooledConnection;
static PreparedStatement psSelectAttrValId;

public FindAttrValIdByIdentifier(long i, String s) throws SQLException {
    super();
    attrId = i;
    identifier = s;
    pooledConnection = SpeedLoader.getConnection();
    psSelectAttrValId = pooledConnection.prepareStatement("SELECT ATTRVAL_ID FROM ATTRVAL WHERE ATTR_ID=? AND IDENTIFIER=? FOR READ ONLY");
}


public static void close() throws SQLException{
    try {pooledConnection.close();} catch (SQLException e) {e.printStackTrace();}
    try {psSelectAttrValId.close();} catch (SQLException e) {e.printStackTrace();}
 }
public Long call()  {
  try  { 
    psSelectAttrValId.setLong(1, attrId);
    psSelectAttrValId.setString(2, identifier);     
    ResultSet rs = psSelectAttrValId.executeQuery();
    if (rs.next()){
        return(rs.getLong(1));
    }
//        System.out.println("Thread " + m_myId +  " is finished. ");
    return 0L;
  } catch (Exception e) {
      System.out.println("Thread got Exception: AtrrId, Identifier= "+attrId+","+identifier+"  Error: " + e);
      e.printStackTrace();
      throw(new Error("AttrId:"+attrId+ " AttrValIdentifier: "+identifier+   " FindAttrValIdByIdentifier.call() "+e.getMessage()));
  } finally {

  }

0 个答案:

没有答案