posts - 31,  comments - 31,  trackbacks - 0
                  到一個這東西都寫到3了,針對上回說到30000條數據的批量插入工作。30000條數據的批量插入在一個事務里處理固然是快,但是這只是測試環境,30000條數據在數據庫的緩存里必然對數數據庫的緩存和鎖數量都是一個大的挑戰,固在新的程序中我們使用了分批事務提交的方式,這樣為了保持數據的正確行就只能人為控制數據庫中已被插入的數據是否delete掉。另外,使用Batch塊提交會引發一個問題就是,如果batch塊中發生了異常,我們得不到異常數據的行號即任何信息,所以只能是魚和熊掌不可兼得(我已關注過insert方法中返回pk的方法了,但好像在batch中他反回不了出錯的行號,也許是我沒有找到方法,如有人有好方法請共享一下,在這里表示感謝),大家酌情考慮吧,只能到到自己需要的平衡點了。
                建議:如果對數據的準確性毋庸置疑的話就是用batch處理。如果不能確定準確性的話,如果對那條數據出錯無所謂的話就也可以用batch,但是非要返回出錯行號的話就不要用batch了,直接在外面套用一個事務,然后try catch一下,處理一下行號。
          posted @ 2007-06-28 21:32 小平 閱讀(3293) | 評論 (4)編輯 收藏
          今天發生了ORA-01461 :can bind a LONG value only for insert into a LONG ...到處查詢發現是一個字段中的中文內容導致,仔細分析了一下原因,是因為jdk1.5的String類型為utf-16編碼方式,而jdk1.4為utf-8,通過在oracle網上查詢10g的jdbc驅動有兩個版本,舊版的不持jdk1.5,只支持jdk1.4,通過換jdbc驅動問題解決。
          posted @ 2007-06-20 10:53 小平 閱讀(2805) | 評論 (0)編輯 收藏
          1、上回的心得中我強調了startBatch()的批處理的作用,但是其中的使用是個錯誤用法,并沒有發揮出startBatch()的實力,對此給與觀眾的誤導我將在此表示到欠,并貼出正確的用法
          public class LocalDaoImpl extends SqlMapClientDaoSupport implements LocalDao {

              
          public void insertBuNaTaxBatLst(final PaginatedList list)
              
          {
                   getSqlMapClientTemplate().execute(
          new SqlMapClientCallback() {
                          
          public Object doInSqlMapClient(SqlMapExecutor executor)
                                  
          throws SQLException {
                              executor.startBatch();
                              
          // do some iBatis operations here
                              for(int i=0,count=list.size();i<count;i++)
                              
          {    
                                  executor.insert(
          "insertBuNaTaxBatLst", list.get(i));
                                  
          if (i % 50 == 0{
                                      System.out.println(
          "----" + i);//沒有意義只為測試
                                  }

                              }

                              executor.executeBatch();
                              
          return null;
                          }

                      }
          );
              }


          }
          這樣才能利用上startBatch()威力。
          2、注意ibatis的事物默認情況下是自動提交的,如果發現速度上有問題可以留意一下,ibatis只有在顯示的聲明事物管理的情況下才自動將事物管理改為不自動方式。
          3、還是startBatch(),據我測試分析這個鬼東西只有在executeBatch(),才把所有的語句提交到數據庫,在提交之前緩存中保留了大量的sql語句和數據對象,很有可能out of memony,對此要留意,可以在大量數據要做插入時,分批用Batch,如:有40000條數據可將其分為4個Batch塊,讓后將這4個Batch用一個事物提交以保證數據完整性。
          注:最近在做數據抽取項目,愿與大家溝通心得
          posted @ 2007-05-30 21:46 小平 閱讀(5968) | 評論 (6)編輯 收藏

          程序功能:
          使用ibatis+spring將oracle數據庫中的tfile表中的數據抽取到db2數據庫的tfile表,這兩個表的結構相同。

          測試環境:
          celeron M 1.4/512M/mysql 5.0數據庫
          代碼:

          public static void main(String[] args) {
                  
          // TODO Auto-generated method stub
                  ClassPathResource resource = new ClassPathResource(
                          
          "applicationContext.xml");
                  BeanFactory factory 
          = new XmlBeanFactory(resource);
                  TFileDAO tFileDao 
          = (TFileDAO) factory.getBean("tfile");

                  TFileDAO test2FileDao 
          = (TFileDAO) factory.getBean("test2tfile");
                  
          //獲取全部數據
                  List list = tFileDao.getAll();
                  
          //開啟事務
                  DataSourceTransactionManager txm = (DataSourceTransactionManager) factory
                          .getBean(
          "test2transactionManager");
                  DefaultTransactionDefinition def 
          = new DefaultTransactionDefinition();
                  def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
                  TransactionStatus status 
          = txm.getTransaction(def);
                  
          try {
                      test2FileDao.getSqlMapClient().startBatch();
                      
          for (int i = 0, count = list.size(); i < count; i++{
                      
          //插入數據
                          test2FileDao.insert((TFile) list.get(i));
                      }

                      test2FileDao.getSqlMapClient().executeBatch();// 這兩句有問題,請見Spring+ibatis心得2!
                  }
           catch (Exception e) {
                      txm.rollback(status);
                      System.out.println(e);
                  }

                  txm.commit(status);
                  System.out.println(list.size());
              }
          1、保證使用長事務,不要在每個插入都事務提交,這樣性能可以有很大幅度的提升
          2、使用 test2FileDao.getSqlMapClient().startBatch();
                        test2FileDao.getSqlMapClient().executeBatch();
                       可以發起jdbc對批量數據插入的優化與自動代碼壓縮功能。

                結語:這次使用ibatis在同樣的硬件、數據庫、數據條數的環境下測試,在不起用batch,所有數據庫,數據池特性均使用默認設置情況下使用19秒,并且使用一次性將數據讀入內存的方式,效果優于hibernate,所以真信優化后的程序應該比hibernate效率更高。但是從程序編寫方面來講,hibernate省去了過多的代碼,可以讓程序員更輕松些。
          posted @ 2007-04-26 19:54 小平 閱讀(3211) | 評論 (1)編輯 收藏

          程序功能:
          使用hibernate+spring將oracle數據庫中的tfile表中的數據抽取到db2數據庫的tfile表,這兩個表的結構相同。(原本要使用一些Spring的特性,但是程序改來改去發現Spring特性一個都沒用上,實際上完全可以由hibernate創建兩個sessionFactory完成)
          測試環境:
          celeron M 1.4/512M/mysql 5.0數據庫
          代碼:

          public void save() {
            Session session
          = fileDAO.getDataSession();
            Session session2
          = fileDAO2.getDataSession();
            Transaction tx 
          =session2.beginTransaction();
            
          int count=0;
            List list 
          =fileDAO.getList(session, count);
            
          while(list.size()!=0)
            
          {
             
          for(int i=0,num =list.size();i<num;i++)
             
          {
              session2.save(list.get(i));
              session.evict(list.get(i));
              
          if(num%50==0)
              
          {
               session2.flush();
               session2.clear();
              }

             }

             count
          = count+500;
             list 
          =fileDAO.getList(session, count);
             
            
          // System.out.println(count);
             
            }

            tx.commit();
            session.close();
            session2.close();
          }

          配置文件:

          <prop key="hibernate.jdbc.batch_size">50</prop>
          <prop key="hibernate.cache.use_second_level_cache">false</prop>

           

          1、為保證不會出現內存溢出
             hibernate.jdbc.batch_size 設為 20-50
             并在代碼中沒隔50個insert后手工清理數據 
               

           if(num%50==0)
              
          {
               session2.flush();
               session2.clear();
              }

          2、為保證減少二級緩存導致的過多的內存開銷關,閉二級緩存
            hibernate.cache.use_second_level_cache 設為false
          3、保證使用長事務,不要在每個插入都事務提交,這樣性能可以有很大幅度的提升(由于原先配的事務沒有正常運行,在初次測試時此程序插入4萬條數據用了12分鐘,使用了長事務后僅為34秒)
          4、使用ScrollableResults(提供了數據庫的游標特性)然后插入的效果好像要優于分批抓取分批插入的效果,(4萬條數據,用ScrollableResult耗時29秒)但網上有人聲稱批量抓取插入的效果要好可能在遠程數據庫的情況下批量抓取的可靠性更高一點的原因。這一點我詢問過公司里做數據庫比較好的人,批量處理數據是要使用游標處理的。就游標而言分為動態游標,靜態游標,動態游標慢于靜態游標,靜態游標慢于靜態查詢,但是如果用分批抓取數據的話就涉及到數據分段截取,為保證每次分段截取時數據的正確性,應該要預先對數據處理,所以批量抽取數據的速度可能會慢一些。以下為使用ScrollableResult的程序
            

          Session session= fileDAO.getDataSession();
            Session session2
          = fileDAO2.getDataSession();
            Transaction tx 
          =session2.beginTransaction();
            ScrollableResults tFiles 
          = session.createQuery(
              
          "from TFile as model ").setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);
            
          int count=0;
            
          while(tFiles.next())
            
          {
             session2.save(tFiles.get(
          0));
             
          if(++count%50==0)
              
          {
               session2.flush();
               session2.clear();
              }

            }

            tx.commit();
            session.close();
            session2.close();
          posted @ 2007-04-24 19:30 小平 閱讀(1803) | 評論 (0)編輯 收藏
          僅列出標題
          共6頁: 上一頁 1 2 3 4 5 6 下一頁 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          framework

          j2me

          java

          linux

          web

          其他

          友情鏈接

          素材

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 太白县| 靖江市| 无棣县| 资讯 | 芒康县| 启东市| 黄冈市| 汶上县| 大化| 平原县| 望城县| 稻城县| 台南县| 饶河县| 永定县| 项城市| 邻水| 阳江市| 郓城县| 龙井市| 友谊县| 新和县| 饶平县| 高淳县| 新源县| 宜州市| 寻乌县| 静海县| 宝兴县| 盐城市| 抚顺县| 伊宁县| 义马市| 沽源县| 弥渡县| 陵川县| 赣州市| 治县。| 云阳县| 日土县| 柳林县|