Mybatis與JDBC批量插入MySQL數據庫性能測試及解決方案


轉自http://www.cnblogs.com/fnz0/p/5713102.html

不知道自己什么時候才有這種鑽研精神- -。

1      背景

系統中需要批量生成單據數據到數據庫表,所以采用批量插入數據庫的方式。由於系統中ORM操作集成使用的是Mybatis來完成的。

 

在Mybatis中操作一般使用批量插入的方式如下:

<insert id="insertBatch" parameterType="java.util.List"  >

     insert into userinfo (uidunameuphoneuaddress)

     values

    <foreach collection="list" item="item"index="index" separator=",">

    (#{item.uid,jdbcType=INTEGER},

     #{item.uname,jdbcType=VARCHAR},

     #{item.uphone,jdbcType=VARCHAR},

     #{item.uaddress,jdbcType=VARCHAR}

     )

   </foreach>

   </insert>

在實際生產中發現,這樣調用的效率並不高,於是我們迫切地需要尋找一種處理批量插入性能較高的方式——回歸原生數據庫JDBC操作。我們要分析Mybatis和JDBC的插入性能,來決策適合我們生產系統的批量插入方式。

 

參考資料中有一篇文章是對Spring Mybatis和Spring JDBC插入效率的測試,由於測試的數據量不多不予置評。

2      Mybatis

2.1  Mybatis測試樣本1K

測試10組數據:

時間(ms)                                                                 

923

412

426

408

405

353

365

344

316

493

 

2.2  Mybatis測試樣本2K

測試10組數據:

時間(ms)                                                                 

11031

3340

3571

2327

7273

1353

2676

1249

1245

1155

 

2.3  Mybatis測試樣本4K

測試10組數據:

時間(ms)                                                                 

6070

5565

5731

5400

5830

5543

5469

5697

5528

5399

 

2.4  Mybatis測試樣本6K

測試10組數據:

時間(ms)                                                                  

13383

12672

13030

13484

13841

12952

13331

13275

13000

13236

 

2.5  Mybatis測試樣本8K

測試10組數據:

時間(ms)                                                                

25312

24702

27065

25921

25156

24686

25314

33947

25304

25853

 

2.6  Mybatis測試樣本10K

測試10組數據:

時間(ms)                                                                

42148

39209

38548

40109

37820

37728

38178

38481

38157

39032

 

2.7  Mybatis測試樣本15K

測試10組數據:

時間(ms)                                                               

98250

88585

87438

89547

88427

89522

83261

80842

87163

84804

 

2.8  Mybatis測試樣本20K

測試10組數據:

時間(ms)                                                               

145481

146618

147098

145578

144947

145614

142014

142315

141984

143625

 

2.9  性能測試樣本平均值

2.9.1  測試樣本SQL

2.9.1.1       毫秒級SQL【time(ms)】

-- DELETE FROMprocess_spend_time_result  WHEREpmethod='mybatis';

 

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=1000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=2000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=4000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=6000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=8000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=15000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=20000 ANDp.pmethod='mybatis';

2.9.1.2       秒級SQL【time(s)】

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=1000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=2000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=4000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=6000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=8000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=15000 ANDp.pmethod='mybatis';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=20000 ANDp.pmethod='mybatis';

2.9.2  測試數據匯總

數據4舍5入保留3位小數

測試樣例                                        

AVG(s)                                              

1K

0.445

2K

3.522

4K

5.623

6K

13.221

8K

26.326

10K

38.941

15K

87.784

20K

144.527

 

2.10    Mybatis批量插入問題

2.10.1             問題一:處理性能低下

處理10000條耗時:34292ms

 

2.10.2             問題二:批量處理數據量大小受限

Windows下需要修改MySQL的my.ini文件加入如下配置內容:

max_allowed_packet=500M

Linux下是在/my.cnf修改添加如上內容。

 

也可以直接這樣設置:

SET GLOBAL max_allowed_packet=1073741824;

但MySQL重啟后就不起作用了。

2.10.3             問題三:線程處理鎖表

在通過多線程並發處理的時,很容易導致數據庫表鎖表,使得后續的操作無法進行。

2.10.4             問題四:導致對象回收GC問題

對象超出GC對象回收閥值,導致程序中斷。

 

3      JDBC

3.1  JDBC測試數據1W

測試10組數據:

 

普通插入(ms)

普通+事務(ms)

普通批量(ms)

批量+事務(MS)

28489

801

31287

3494

30536

3042

35547

1899

25571

2041

31022

3501

27954

2733

28927

2547

29620

1261

34408

1449

27125

819

29318

923

28993

1079

31099

939

27594

2547

33504

3410

27967

781

31646

3587

33145

1293

37030

1912

 

3.2  JDBC測試數據5W

測試10組數據:

 

普通插入(ms)

普通+事務(ms)

普通批量(ms)

批量+事務(MS)

131427

11568

168623

6926

132271

19313

231526

9915

192176

5238

227724

10978

185640

18955

227497

41959

211777

11238

184970

9461

208446

5019

263636

23394

253351

14265

227391

24870

225268

17009

229871

5583

163739

9719

230719

16657

215033

15802

238018

5330

 

3.3  JDBC測試數據10W

測試10組數據:

 

普通插入(ms)

普通+事務(ms)

普通批量(ms)

批量+事務(MS)

308773

21389

360510

16432

352773

23487

372343

25545

378805

24034

368416

12507

384189

30119

392974

23742

369975

30651

378634

26180

368659

11902

416932

21321

388453

12644

411571

18138

391155

11287

396363

11678

368055

30987

399078

12212

363375

22576

361478

18544

 

3.4  JDBC測試數據25W

測試10組數據:

 

普通插入(ms)

普通+事務(ms)

普通批量(ms)

批量+事務(MS)

942067

51343

990800

70103

1070688

28737

1051132

35536

1002076

38065

1222409

89644

1073114

57050

1312620

82354

960697

51733

1338932

33428

1025890

37666

1273338

76934

1017361

50916

1115627

92790

1077821

78650

1175512

52427

1038000

23290

1247797

91801

1200532

75494

1262051

72087

 

3.5  JDBC測試數據50W

測試10組數據:

 

普通插入(ms)

普通+事務(ms)

普通批量(ms)

批量+事務(MS)

1914920

166575

2059826

146472

2111596

62807

1897888

125075

2174029

147265

1891542

166921

1948838

61284

2129791

93167

1909861

167575

1856811

56286

1990816

141381

1980060

148012

1896793

48087

2065937

56832

2130856

174388

2019914

113289

2073636

117462

2045715

102792

1966828

141319

1857867

116854

 

3.6  JDBC測試樣本均值

3.6.1  測試樣本SQL

3.6.1.1       毫秒級SQL【time(ms)】

 

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod='batchInsertWithTransaction2';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod='batchInsertWithTransaction2';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod='batchInsertWithTransaction2';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod='batchInsertWithTransaction2';

SELECTAVG(p.ptime) FROM process_spend_time_resultp WHEREp.plimit=500000andp.pmethod='batchInsert';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod='batchInsertWithTransaction2';

 

3.6.1.2       秒級SQL【time(s)】

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 andp.pmethod='batchInsertWithTransaction2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime)/1000 FROM process_spend_time_resultp WHEREp.plimit=50000andp.pmethod='batchInsertWithTransaction2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 andp.pmethod='batchInsertWithTransaction2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=250000 andp.pmethod='batchInsertWithTransaction2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod='batchInsert';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod='batchInsert2';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod='batchInsertWithTransaction';

SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=500000 andp.pmethod='batchInsertWithTransaction2';

 

3.6.2  測試數據匯總

數據4舍5入保留2位小數

測試樣例

1W(s)               

5W(s)               

10W(s)              

25W(s)                

50W(s)                               

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事務

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事務

2.37

15.51

18.63

69.71

112.57

3.7  JDBC測試規律總結

3.7.1  規律一:批量插入盡量使用事務控制

數據4舍5入保留2位小數

測試樣例

1W(s)               

5W(s)                

10W(s)              

25W(s)               

50W(s)                               

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事務

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事務

2.37

15.51

18.63

69.71

112.57

 

3.7.2  規律二:事務批量處理的數據量不要太大

數據4舍5入保留2位小數

測試樣例

1W(s)              

5W(s)                 

10W(s)              

25W(s)                

50W(s)                              

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事務

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事務

2.37

15.51

18.63

69.71

112.57

3.7.3  規律三:適當地設置MySQL參數可以提高數據庫性能

數據4舍5入保留2位小數

測試樣例

1W(s)              

5W(s)                 

10W(s)              

25W(s)                 

50W(s)                             

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事務

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事務

2.37

15.51

18.63

69.71

112.57

3.7.4  規律四:處理數據量和時間不是成倍增長

數據4舍5入保留2位小數

測試樣例

1W(s)              

5W(s)                 

10W(s)              

25W(s)                  

50W(s)                            

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事務

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事務

2.37

15.51

18.63

69.71

112.57

3.7.5  規律五:數據庫性能隨數據量的不斷加大而降低

數據4舍5入保留2位小數

測試樣例

1W(s)                

5W(s)               

10W(s)              

25W(s)                  

50W(s)                            

普通插入

28.70

191.91

367.42

1040.82

2011.82

普通+事務

1.64

12.81

21.91

49.29

122.81

批量插入

32.38

223.00

385.83

1199.02

1980.54

批量+事務

2.37

15.51

18.63

69.71

112.57

 

4      結論

經過以上測試得出結論:Mybatis的批量適合處理少了數據的批量處理,而JDBC適合大數據量的批量處理。據此,采用JDBC批量+事務處理大數據量的表插入操作是最合適的。

5      方案

因為要考慮JVM的GC所以數據應該限制一下,但鑒於Mybatis大數據量的批量插入效率不高,所以根據數據大小分段治理。

 

5.1  小於1W使用:Mybatis批量插入方案

對JVM進行調優,但主要的性能瓶頸在批量插入操作。鑒於mybatis在項目開發方面的優勢,數據量很小的情況下還是建議使用Mybatis。

 

5.2  大於1W小於10W使用:JDBC批量+事務處理

對JVM進行調優(設置Stack和GC等)。一般操作30秒以內是可以容忍的性能耗時。

5.3  10W以上數據使用:數據分批+JDBC批量+事務處理

對JVM進行調優(設置Stack和GC等),通過數據分批處理。對於分批處理需要借鑒前面的測試數據來定義分批量的大小,主要是對操作時間調優。

 

如果是100W、1000W級別的數據量,分批處理可以很大程度地提升插入效率,具體的分批需要通過實踐去分配,數據量太大這里就不做實驗了。

6      參考資料

JDBC實現往MySQL數據庫插入百萬數據:http://www.cnblogs.com/fnz0/p/5713102.html

 

 

MySQL Max_allowed_packet: http://stackoverflow.com/questions/8062496/how-to-change-max-allowed-packet-size

 

Spring Mybatis和Spring JDBC的插入效率比較:http://toplchx.iteye.com/blog/1988254

 

注:另外一種比較高效的導入方式是生成一個文本文件使用MySQL的JDBC LOAD DATA LOCAL INFILE;參考示例:

MySQL使用JDBC LOAD DATA LOCAL INFILE導入注意事項

MySQL使用LOAD DATA LOCAL INFILE數據3-5秒導入40W數據

Java不寫文件,LOAD DATA LOCAL INFILE大批量導入數據到MySQL的實現

7.實戰演練

注意:事務處理的數據量不能太多。

 

7.1  JDBC工具類

 

 

package com.wlyd.fmcgwms.util.jdbc;

 

import java.io.IOException;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.util.Properties;

/**

 *JDBC連接工具類

 *

 *@package com.wlyd.fmcgwms.util.jdbc.JdbcConnection

 *@date   2017年4月17日  下午3:32:15

 *@author pengjunlin

 *@comment  

 *@update

 */

public class JdbcConnection {

        

         privatestatic Connection conn = null; 

        

   private static Properties props = null; 

 

   static { 

       props = new Properties(); 

       try { 

           props.load(JdbcConnection.class.getResourceAsStream("/jdbc.properties")); 

       } catch (IOException e1) { 

           e1.printStackTrace(); 

       } 

       try { 

           Class.forName(props.getProperty("jdbc.driverClass")); 

       } catch (ClassNotFoundException e) { 

           e.printStackTrace(); 

       } 

    }

 

   public static Connection getConn(){ 

       try { 

           conn = DriverManager.getConnection(props.getProperty("jdbc.jdbcUrl"),props.getProperty("jdbc.user"),props.getProperty("jdbc.password")); 

           conn.setAutoCommit(false); 

       } catch (SQLException e) { 

           e.printStackTrace(); 

       } 

       return conn; 

   } 

     

   public void closeConn(){ 

       try { 

           if (conn != null) 

                conn.close(); 

       } catch (SQLException e) { 

           e.printStackTrace();

       } 

         

   } 

 

}

 

7.2  批量事務插入

7.2.1  接口

 /**

     * jdbc批量插入

     *

     * @MethodName: jdbcBatchInsert

     * @Description:

     * @param user

     * @param items

     * @return

     * @throws Exception

     * @throws

     */

    int jdbcBatchInsert(EsUser user,List<WmElectronicSheetItem> items) throws Exception;

   

    /**

     * jdbc批量插入

     *

     * @MethodName: jdbcPerBatchInsert

     * @Description:

     * @param user

     * @param items

     * @return

     * @throws Exception

     * @throws

     */

    intjdbcPerBatchInsert(EsUser user, List<WmElectronicSheetItem> items)  throws Exception;

7.2.2  實現

@Override

    publicint jdbcBatchInsert(EsUser user, List<WmElectronicSheetItem> items) throws Exception {

        intflag = 0;

 

        intperCount = 100, index = 0;

 

        inttimes = items.size() / perCount;

        longstime=System.currentTimeMillis();

        try {

            do {

                // 休眠50ms

                Thread.sleep(50);

                List<WmElectronicSheetItem>listTemp= null;

                if (items.size() >= perCount) {

                    listTemp = items.subList(0, perCount);// listTemp是分段處理邏輯的參數

                }else{

                    listTemp = items.subList(0, items.size());// listTemp是分段處理邏輯的參數

 

                }

                // 遍歷當前的值是否正確

                Stringresult= "";

                for (inti = 0; i < listTemp.size(); i++) {

                    result += listTemp.get(i) + ",";

                }

                Log.getLogger(getClass()).info("第" + (index+1)+ "輪:>>" + result);

               

                // 事務單元執行個數==盡量在事務里面處理少一點(事務盡量小一點)

                jdbcPerBatchInsert(user, listTemp);

 

                items.removeAll(listTemp);

 

                Log.getLogger(getClass()).info("當前剩余集合長度:>>" + items.size());

 

                index++;

            }while(index<= times);

            // 計算時間

            longetime=System.currentTimeMillis();

            Log.getLogger(getClass()).info(">>封裝面單號批量事務插入總共耗時-----------------------:"+(etime-stime)+"ms!");

        }catch(Exception e) {

            e.printStackTrace();

            flag=2;

            Log.getLogger(getClass()).error("JDBC批量執行插入異常:>>" + items.size());

            thrownew RuntimeException();

        }

 

        returnflag;

    }

 

 

    @Override

    publicintjdbcPerBatchInsert(EsUser user, List<WmElectronicSheetItem> items)

            throws Exception {

        intflag=0;

        Connectionconn=JdbcConnection.getConn();

        PreparedStatementpstm= null;

        try {

            Stringsql= "insert intowm_electronic_sheet_item_?  ("

                    +"WESI_WESB_ID,WESI_CARRIER_CODE,WESI_START_CHARACTER,WESI_SEQUENCE,"

                    +"WESI_WAREHOUSE_ID, WESI_CODE,WESI_STATE, "

                    +"CREATOR, CREATE_TIME, MODIFIER,MODIFY_TIME) values"

                    +"(?, ?, ?,  ?, ?, ?, ?, ?, ?, ?, ?)";

            conn.setAutoCommit(false);

            Log.getLogger(getClass()).info(">>>>>>驗證JDBC連接:"+(conn!=null));

            for (inti = 0, j = items.size(); i < j; i++) {

                WmElectronicSheetItemitem= items.get(i);

                pstm = conn.prepareStatement(sql);

                pstm.setInt(1, Integer.valueOf(user.getEsCorCode())); // tableName

                pstm.setInt(2, item.getWesiWesbId());// WESI_WESB_ID

                pstm.setString(3, item.getWesiCarrierCode());// WESI_CARRIER_CODE

                pstm.setString(4, item.getWesiStartCharacter());// WESI_START_CHARACTER

                pstm.setString(5, item.getWesiSequence());// WESI_SEQUENCE

                pstm.setInt(6, item.getWesiWarehouseId());// WESI_WAREHOUSE_ID

                pstm.setString(7, item.getWesiCode());// WESI_CODE

                pstm.setInt(8, item.getWesiState());// WESI_STATE

                pstm.setInt(9, user.getEsId());// CREATOR

                pstm.setTimestamp(10,new java.sql.Timestamp(new Date().getTime()));// CREATE_TIME

                pstm.setInt(11, -1);// MODIFIER

                pstm.setTimestamp(12, null);// MODIFY_TIME

                pstm.executeUpdate();

            }

            conn.commit();// 手動提交事務

        }catch(Exception e) {

            e.printStackTrace();

            flag=2;

            Log.getLogger(getClass()).error("JDBC批量分配事務單元執行插入異常:>>" + items.size());

            thrownew RuntimeException();

        }finally{

            if (pstm != null) {

                try {

                    pstm.close();

                }catch(SQLException e) {

                    e.printStackTrace();

                }

            }

            if (conn != null) {

                conn.close();

            }

        }

        returnflag;

    }

 

7.3測試一組數據

測試50000條數據耗時統計:

 

 

數據樣本事務大小 (每個事務處理的數量)                                

         耗時(ms)                                             

100

100258

500

75041

1000

68850

3000

78354


通過這種方式提交比較安全不會出現線程鎖表問題,事務處理盡量少,根據每次事務提交執行的量可以實現時間上的優化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM