需求是這樣的:現有100萬條資料需要插入oracle資料庫,資料源格式為xml格式,需要決議,提取出關鍵資料,寫入資料庫。決議,寫入資料庫都沒問題,但是到2000多條的時候記庫失敗,寫不了資料庫。代碼如下:
public class DBhelp {
static String driverClass="oracle.jdbc.driver.OracleDriver"; //oracle的驅動
static String url="jdbc:oracle:thin:@192.168.5.16:1521:noCard";
static String user="card22";//user是資料庫的用戶名
static String password="card11";
public static Connection getconn() { //為了方便下面的講解,這里專門建立了一個用于資料庫連接的一個方法
Connection conn=null;
try {
//首先建立驅動
Class.forName("oracle.jdbc.driver.OracleDriver");
//驅動成功后進行連接
conn=DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return conn; //回傳一個連接
}
public static int insert(String sql){
Connection conn=null;
Statement st=null;
conn=getconn();
//獲得連接
int result;
try {
st=conn.createStatement();
//創建插入的sql陳述句
//回傳一個進行此操作的結果,要么成功,要么失敗,如果回傳的結果>0就是成功,反之失敗
result=st.executeUpdate(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
result=0;
e.printStackTrace();
}
return result;
}
}
sql陳述句:
try {
String sql="insert into JingDong(TRX_CODE) values('"+trx_code+"'')";
logger.info("sql:"+sql);
int aa= DBhelp.insert(sql);
} catch (JDOMException e) {
logger.info("報文解釋出錯,報文格式不正確");
} catch (Exception e) {
logger.info("錯誤:"+e.getMessage());
}
e.getMessage()--輸出null
uj5u.com熱心網友回復:
代碼貼全了嗎? 沒有看到你關 連接,uj5u.com熱心網友回復:
你是說我連接沒關引起的
uj5u.com熱心網友回復:
像這種百萬級的操作,是否要使用連接池
uj5u.com熱心網友回復:
etl kettle吧 比寫代碼簡單多了uj5u.com熱心網友回復:
從例外日志看,你這個錯誤應該是 NullPointerException 例外沒打全是因為:
catch (Exception e) {
logger.info("錯誤:"+e.getMessage());
}
應該寫成這樣才能把例外堆疊完整列印出來:
catch (Exception e) {
logger.info("錯誤:",e);
}
或者這樣
catch (Exception e) {
e.printStackTrace();
}
uj5u.com熱心網友回復:
public static int insert(String sql) throws SQLException{
Connection conn=null;
Statement st=null;
conn=getconn();
//獲得連接
int result;
try {
st=conn.createStatement();
//創建插入的sql陳述句
//回傳一個進行此操作的結果,要么成功,要么失敗,如果回傳的結果>0就是成功,反之失敗
result=st.executeUpdate(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
result=0;
e.printStackTrace();
}finally
{
if(null!=conn)
{
conn.close();
conn=null;
}
if(null!=st)
{
st.close();
st=null;
}
}
return result;
}
這樣改了下,加上關閉連接,不報上邊的錯誤了,確實是沒有關閉連接,持續向資料庫寫入30萬筆資料,結果有10047筆沒有寫入,這個什么原因
uj5u.com熱心網友回復:
插入資料的代碼是什么? 哪部分資料沒插入呢? 資訊太少,不好判斷
uj5u.com熱心網友回復:
用以上方法插入資料,以前一筆是24毫秒,現在100毫秒,插入100萬筆資料,是否要使用連接池uj5u.com熱心網友回復:
用以上方法插入資料,以前一筆是24毫秒,現在100毫秒,插入100萬筆資料,是否要使用連接池
用啥連接池...你就一個主執行緒,連接不用關閉,直接用一個connection就行了.
如果你想提升性能,多執行緒 + 批量插入
uj5u.com熱心網友回復:
100萬條資料。。。換一種思路吧,考慮一下,能否使用PLSQL實作。
uj5u.com熱心網友回復:
public boolean insertDetailed(List<Detailed> listDetailed){long start = System.currentTimeMillis();
PreparedStatement pstmt=null;
StringBuffer sql=new StringBuffer();
int result=0;
try {
sql.append("insert INTO Detailed(id,DETAILNUMBER,payeebankname)");
sql.append(" values");
sql.append("(seq_detailed.nextval,?,?,?)");
pstmt=getConnection().prepareStatement(sql.toString());
for(int i = 0 ; i < listDetailed.size();i++){
Detailed detailed = listDetailed.get(i);
pstmt.setObject(1, detailed.getDetailnumber());//序列 DateUtil.get4yMdHms(new Date())
pstmt.setObject(2, detailed.getPayeebankname());
pstmt.addBatch();
if(i%500==0){
pstmt.executeBatch();
}
}
pstmt.executeBatch();
// getConnection().commit();
long end = System.currentTimeMillis();
System.out.println("批量插入需要時間:"+(end - start)+"ms"); //批量插入需要時間:24675
} catch (Exception e) {
LogUtil.saveLogSqlException(sql.toString(),e);
e.printStackTrace();
}finally{
closeState(pstmt, rs);
}
return result>0?true:false;
}
uj5u.com熱心網友回復:
使用批量插入試試,網上查的貼子:uj5u.com熱心網友回復:
https://blog.csdn.net/u014763502/article/details/84338348uj5u.com熱心網友回復:
DBhelp.insert(sql); //你這里每次都建一個鏈接去執行sql,目前懷疑是連接不夠的原因;
//另外你這里,也會再面臨一個問題,就是表空間增長與擴容的問題,會導致插入資料效率很低。
你可以看看我之前發的一個帖子:1000W INSERT陳述句,快速插入ORACLE
uj5u.com熱心網友回復:
servlet有執行時間限制,插入100w資料可能會超時,最好寫成服務uj5u.com熱心網友回復:
代碼改掉用批處理uj5u.com熱心網友回復:
應該是要用連接池的吧,這么大的資料量uj5u.com熱心網友回復:
別用jdbc 用連接池uj5u.com熱心網友回復:
我猜你呼叫的時候直接就是一個回圈呼叫insert方法,而你到2000就失敗的原因是因為不斷的創建連接吧資料庫的連接都占滿了,無法創建新連接導致的,
解決方式一,只創建一個連接,然后回圈插入
解決方式二,實作一個連接池
上面兩種方式只是為了讓你插入能成功,至于性能方面,樓主沒提,就不討論了
uj5u.com熱心網友回復:
百萬級別的估計要用連接池,還有可以用多執行緒uj5u.com熱心網友回復:
每次insert都去創建一個conn?這是要累死資料庫還是累死誰呢?你就不可以一個con批量insert?轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/80274.html
標籤:Java EE
下一篇:vue+springboot向后端傳資料報錯Current request is not a multipart request
