java servlet循环向oracle插入100万条数据的问题,请高手帮忙解决,着急

zhangfengyi 2020-04-17 07:28:53
需求是这样的:现有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
...全文
595 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
csdn越来越坑 2020-04-30
  • 打赏
  • 举报
回复
每次insert都去创建一个conn?这是要累死数据库还是累死谁呢?你就不可以一个con批量insert?
dhacker1 2020-04-30
  • 打赏
  • 举报
回复
百万级别的估计要用连接池,还有可以用多线程
ITjavaman 2020-04-30
  • 打赏
  • 举报
回复
我猜你调用的时候直接就是一个循环调用insert方法,而你到2000就失败的原因是因为不断的创建连接吧数据库的连接都占满了, 无法创建新连接导致的, 解决方式一,只创建一个连接,然后循环插入 解决方式二,实现一个连接池 上面两种方式只是为了让你插入能成功,至于性能方面,楼主没提,就不讨论了
Dkodak 2020-04-30
  • 打赏
  • 举报
回复
别用jdbc 用连接池
五哥 2020-04-29
  • 打赏
  • 举报
回复
https://blog.csdn.net/u014763502/article/details/84338348
五哥 2020-04-29
  • 打赏
  • 举报
回复
使用批量插入试试,网上查的贴子:
五哥 2020-04-29
  • 打赏
  • 举报
回复
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;
}
  • 打赏
  • 举报
回复
应该是要用连接池的吧,这么大的数据量
编码行者 2020-04-29
  • 打赏
  • 举报
回复
代码改掉用批处理
tianfang 2020-04-29
  • 打赏
  • 举报
回复
servlet有执行时间限制,插入100w数据可能会超时,最好写成服务
Nihility/ 2020-04-29
  • 打赏
  • 举报
回复

DBhelp.insert(sql);  //你这里每次都建一个链接去执行sql,目前怀疑是连接不够的原因;
                     //另外你这里,也会再面临一个问题,就是表空间增长与扩容的问题,会导致插入数据效率很低。
你可以看看我之前发的一个帖子:1000W INSERT语句,快速插入ORACLE
sun0322 2020-04-23
  • 打赏
  • 举报
回复
100万条数据。。。 换一种思路吧,考虑一下,能否使用PLSQL实现。
maradona1984 2020-04-23
  • 打赏
  • 举报
回复
引用 8 楼 zhangfengyi 的回复:
用以上方法插入数据,以前一笔是24毫秒,现在100毫秒,插入100万笔数据,是否要使用连接池
用啥连接池...你就一个主线程,连接不用关闭,直接用一个connection就行了. 如果你想提升性能,多线程 + 批量插入
zhangfengyi 2020-04-23
  • 打赏
  • 举报
回复
用以上方法插入数据,以前一笔是24毫秒,现在100毫秒,插入100万笔数据,是否要使用连接池
dkwuxiang 2020-04-19
  • 打赏
  • 举报
回复
引用 6 楼 zhangfengyi 的回复:
[quote=引用 1 楼 dkwuxiang 的回复:] 代码贴全了吗? 没有看到你关 连接,

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笔没有写入,这个什么原因[/quote] 插入数据的代码是什么? 哪部分数据没插入呢? 信息太少,不好判断
fly9i 2020-04-18
  • 打赏
  • 举报
回复
从异常日志看,你这个错误应该是 NullPointerException 异常没打全是因为:

catch (Exception e) {
    logger.info("错误:"+e.getMessage());
}
应该写成这样才能把异常栈完整打印出来:

catch (Exception e) {
    logger.info("错误:",e);
} 
或者这样

catch (Exception e) {
    e.printStackTrace();
} 
zhangfengyi 2020-04-18
  • 打赏
  • 举报
回复
引用 1 楼 dkwuxiang 的回复:
代码贴全了吗? 没有看到你关 连接,


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笔没有写入,这个什么原因
tianfang 2020-04-17
  • 打赏
  • 举报
回复
etl kettle吧 比写代码简单多了
zhangfengyi 2020-04-17
  • 打赏
  • 举报
回复
引用 1 楼 dkwuxiang 的回复:
代码贴全了吗? 没有看到你关 连接,

像这种百万级的操作,是否要使用连接池
zhangfengyi 2020-04-17
  • 打赏
  • 举报
回复
引用 1 楼 dkwuxiang 的回复:
代码贴全了吗? 没有看到你关 连接,

你是说我连接没关引起的
加载更多回复(1)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧