在流程完成之前打开新的数据库连接或保持连接打开是否合适?

时间:2012-11-14 07:24:02

标签: java groovy mybatis

我有2个数据库old& newold db详细信息需要过滤/操作并存储到new中。

  

OLD DB

  1. 我有大约10000个配置(数据库行)

  2. 和10000 BLOBS(xml文件大小平均为4MB)匹配上面的配置ID

  3.   

    NEW DB

    1. 1个新表将包含旧的过滤数据,但这次没有BLOB数据,而是绝对路径

    2. 并根据配置提出一些建议

    3. 在这里,我编写了一个程序(使用Groovy& MyBatis for DB),它获取OLD DB中可用的所有配置记录,并存储在类列表中,并且数据库连接已关闭

      为了获取每个配置ID的BLOBS,建立一个新连接&保持开放很长时间

      List<String> projectid
      List<CSMConfigInfo> oldConfigs
      List<ConfigInfo> newConfigs 
      Map<String,CSMConfigInfo> oldConfigMap
      
      SqlSession session = DatabaseConnectivity.getOldCSMDBSessionFactory().openSession()
      /*  trying to batch execute based on project id */
          projectid.each {pid->
              logger.info "Initiating conversion for all configuration under $pid project id"
              oldConfigMap.each {k,v->
      /*  Here I am keeping a DB connection open for a long time */           
                  if(pid.equals(v)){                  
                      createFromBlob(k,session)                   
                  }
              }                       
              logger.info "Completed for $pid project id\n"           
          }
      
      session.close()
      

      在获取BLOB 1之后,我创建了一个临时xml文件,该文件被解析以应用过滤器以插入NEW DB。在代码下面,您可以看到,根据xml是否可转换和可解析,为NEW DB打开了一个新连接。这是一个好的做法,还是我需要保持所有10000条记录的NEW DB连接?

      /* XML is converted to new format and is parsable */
      def createFromBlob(CSMConfigInfo cfg,SqlSession oldCSMSession){
          .
          .
      
          if(xmlConverted&&xmlParsed){
              //DB Entries
              try{
                  /* So now here I am opening a new connection for every old config record, which can be 10000 times too, depending on the filter */
                  SqlSession sess = DatabaseConnectivity.getNewCSMSessionFactory().openSession()
      
                  //New CSM Config
                  makeDatabaseEntriesForConfiguration(newConfig,sess)
                  //Fire Rules
                  fireRules(newConfig,sess,newCSMRoot)
      
                  sess.close()
      
              }
              catch(IOException e){
                  logger.info "Exception with ${newConfig.getCfgId().toString()} while making DB entries for CONFIG_INFO"
              }
              logger.info "Config id: "+cfg.getCfgId().toString()+" completed successfully, took "+getElapsedTime(startTime)+ " time. $newabspath"
          }
          else{
              def errormsg = null
              if(!xmlConverted&&!xmlParsed)
                  errormsg = "Error while CONVERSION & PARSING of config id "+cfg.getCfgId().toString()+", took "+getElapsedTime(startTime)+ " time."
              else if(!xmlConverted)
                  errormsg = "Error while CONVERSION of config id "+cfg.getCfgId().toString()+", took "+getElapsedTime(startTime)+ " time."
              else if(!xmlParsed)
                  errormsg = "Error while PARSING  of config id "+cfg.getCfgId().toString()+", took "+getElapsedTime(startTime)+ " time."
              logger.info errormsg
          }
      
          makeDatabaseEntriesForConvertStatus(csmConfigConvertStatus,oldCSMSession)
      }
      

      这目前适用于20条记录,但我不确定它对所有10000条记录的反应如何。请帮忙

      更新

      每个配置大约需要3-6秒

2 个答案:

答案 0 :(得分:4)

使用数据库连接池总是更有效率,让容器在需要时管理建立和关闭该连接。创建连接,执行语句然后关闭该连接可以通过一个池来避免,该池在给你连接使用之前预先连接,在大多数情况下(所描述的细节)不需要给出连接它可能已经连接。

因此,是的,保持连接开放更有效,甚至更好地集中连接......

答案 1 :(得分:2)

根据我的经验,在循环的每个循环中创建新连接时通常会产生开销。如果打开连接需要0.1秒,那么对于10000条记录,您的时间开销将是1,000秒(大约17分钟)。如果您在超过10,000条记录时保持连接打开而不关闭它,则可以节省17分钟。我想你需要节省17分钟以及关闭和重新创建10,000次连接所需的CPU资源。打开循环外的连接,并在循环后关闭它。

尝试修改方法createFromBlob,以便它接受两个这样的会话;

def createFromBlob(CSMConfigInfo cfg,SqlSession oldCSMSession, SqlSession newCSMSession){

然后替换此代码块;

        /* So now here I am opening a new connection for every old config record, which can be 10000 times too, depending on the filter */
        SqlSession sess = DatabaseConnectivity.getNewCSMSessionFactory().openSession()

        //New CSM Config
        makeDatabaseEntriesForConfiguration(newConfig,sess)
        //Fire Rules
        fireRules(newConfig,sess,newCSMRoot)

        sess.close()

有了这个;

 //New CSM Config
        makeDatabaseEntriesForConfiguration(newConfig,newCSMSession)
        //Fire Rules
        fireRules(newConfig,newCSMSession,newCSMRoot)

然后你必须在开始循环之前创建传递新的SqlSession,并将它传递给你修改过的方法(createFromBlob