批量插入,数据丢失

kjs008 2011-08-06 02:51:47
我想插入100W条数据,但是插入的数据这么都是30W条多点,不知为什么???,下面是代码,



long total = total + 1000000000l; //total=100W
String sql = "insert into student values(?,?,?,?,?)";

Connection conn = DButils.getConnection();
PreparedStatement st = null;
int t = 1;

conn.setAutoCommit(false);
st = conn.prepareStatement(sql);
for(long i=1000000001; i<= total; i++){
st.setLong(1, i);
st.setString(2, i+"");
st.setInt(3, 20);
st.setInt(4, i%2==0?0:1);
st.setDate(5, new Date(86,8,6));
st.addBatch();
if(t++%100000 == 0) { st.executeBatch(); t=1; }
}
st.executeBatch();
conn.commit();

...全文
854 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
ihuanling 2011-08-09
  • 打赏
  • 举报
回复
13楼太彪悍了。。这都发现了。。
softroad 2011-08-09
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 wula0010 的回复:]

一次插入10万条记录,放到一个事务里,最后提交,这个是不可行的,数据库是有锁机制的,插入数据后如果不提交,会用记录锁的,如果你的事务占用了太多的锁,会有问题的,所以对这样的需求,应该分批次提交,比如1000条记录提交一次。
[/Quote]

那如果10w条有一条失败了,如何回滚呢?
wula0010 2011-08-09
  • 打赏
  • 举报
回复
一次插入10万条记录,放到一个事务里,最后提交,这个是不可行的,数据库是有锁机制的,插入数据后如果不提交,会用记录锁的,如果你的事务占用了太多的锁,会有问题的,所以对这样的需求,应该分批次提交,比如1000条记录提交一次。
kjs008 2011-08-09
  • 打赏
  • 举报
回复
发现问题了,一次性提交10W条太多了。下面一句话网上抄的:

在用jdbc的(executeBatch)批量处理时一定注意最大上限,否则只会执行一部分sql语句,超过上限的sql会自动丢弃。
luohuijun619 2011-08-09
  • 打赏
  • 举报
回复
lz一次提交100w条数据,可能connection最大提交数不允许这么多,建议lz每10w时,提交一次事务
xinxian13 2011-08-09
  • 打赏
  • 举报
回复
为了成功插入并且 不重复,建议lz手动地一条一条地插,直到插完插到手抽筋为止
magong 2011-08-09
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 codolio 的回复:]

(1)long total = total + 1000000000l; //total=100W
1000000000l最后是一个小写L吧?
(2)for(long i=1000000001; i<= total; i++){
1000000001最后是一个数字1吧?
[/Quote]
佩服。
我就没往这里想。
wula0010 2011-08-09
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 softroad 的回复:]
那如果10w条有一条失败了,如何回滚呢?
[/Quote]

不知道你的业务逻辑是什么,插入10万条,如果有1条失败了,为什么要回滚?而不是记录哪个失败了,重新去处理?我们有类似的业务,是定时把文本数据导入到数据库,经常会有各种不可预料的原因或者文本中有乱码而导入失败,我是把失败的记录写入一个错误文件,单独处理错误的数据。
developer_java 2011-08-09
  • 打赏
  • 举报
回复
用多线程插入试试 起10个线程进行插入操作
codolio 2011-08-08
  • 打赏
  • 举报
回复
(1)long total = total + 1000000000l; //total=100W
1000000000l最后是一个小写L吧?
(2)for(long i=1000000001; i<= total; i++){
1000000001最后是一个数字1吧?
qian119110 2011-08-08
  • 打赏
  • 举报
回复

if(t++%100000 == 0) {
st.executeBatch();
st.clearBatch();//这个忘记加了吧

t=1;

}


softroad 2011-08-08
  • 打赏
  • 举报
回复
for(long i=1000000001; i<= total; i++){
st.setLong(1, i);
st.setString(2, i+"");
st.setInt(3, 20);
st.setInt(4, i%2==0?0:1);
st.setDate(5, new Date(86,8,6));
st.addBatch();
if(t++%100000 == 0) { st.executeBatch(); t=1; }
}

t=1又从来了?
kjs008 2011-08-08
  • 打赏
  • 举报
回复
我知道我的代码复制过来,删掉一些后,看上去会有些问题,比如:

long total = total + 1000000000l; //total=100W

但是请不要纠结这些细节性的东西,这种细节在真正写程序的时候注意下就可以了,贴到这里的代码是原系统copy过来肯定是可以运行的,去掉一些东西后的可能会出现一些编译时错误但是不影响问题的描述的。
jingluo 2011-08-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 starparker 的回复:]

Java code

long total = total + 1000000000l; //total=100W



Java code

for(long i=1000000001; i<= total; i++){



难道这个程序能插入数据?
[/Quote]

++
「已注销」 2011-08-06
  • 打赏
  • 举报
回复

long total = total + 1000000000l; //total=100W



for(long i=1000000001; i<= total; i++){


难道这个程序能插入数据?
v1srine 2011-08-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zlwork_84 的回复:]
多插两次不就可以了。
欢迎光临我的博客
[/Quote]
+1
半夜郎中 2011-08-06
  • 打赏
  • 举报
回复
我以前用过preparedstatement进行过批处理,好像问什么问题,你换preparedstatement式一下
kjs008 2011-08-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 java_pengjin 的回复:]

不知道你定义那个long total干什么用 就程序而言没看出什么问题
[/Quote]

没必要纠结这些,这只是我摘过来的一部分,total本来是个函数参数,表示要插入多少条数据,

total = total + 1000000000l 表示1000000000是id字段的前缀,是种格式方面的要求.
magong 2011-08-06
  • 打赏
  • 举报
回复
主键字段重复了吗?
super_href 2011-08-06
  • 打赏
  • 举报
回复
不知道你要t干什么~完全不必要这样~~再说插入100W条数据而且提交方式改为手动!你知道你的IDE吃得消啊!!!
加载更多回复(2)

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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