mysql streaming_记一个 MySQL Streaming result set 时的小错误

同事使用kettle迁移MySQL数据时出现了 SQLException,详细报错信息如下:

经查询MySQL官方文档(MySQL版本 5.1-8.0 一样),发现报错原因是JDBC没有处理完resultSet结果集时又使用同一个connection提交了新的query。下面是官方文档对ResultSet的JDBC实现说明:

默认情况下,ResultSet会一次性返回结果集并保存在内存中。这也是最有效率且最容易实现的一种方式。但是当ResultSet含有大量数据(很多行、或者包含大对象的情况下)时,JVM可能无法分配ResultSet要求的内存,这时你可以让driver每次返回(stream)一行数据。

要开启这个功能,需要以如下的方式来创建Statement:

注意上面的statement创建语句,使用了 TYPE_FORWARD_ONLY、CONCUR_READ_ONLY,并将fetchSize设置为 Integer.MIN_VALUE。这种设置告诉driver需要逐行处理 result set。

这种方式也有风险。在使用同一个 connection 来发起新的查询之前,你必须:1)读取 result set中的全部数据;2)或者将其关闭。否则就会抛出我们前面所说的异常。

下面来说说事务。此 Statement 持有的锁最快也要在statement 结束时才能释放。这里的锁包括了 MyISAM的表级锁或者InnoDB的行锁。

当 Statement处在事务中时,锁将在事务完成时释放(事务结束了,当然此Statement也完成了)。像大多数其他数据库一样,Statement只能在其中的所有results都被读取,或者相应的Result set被关闭之后才能关闭。

所以如果使用了streaming results 而又想并发访问相应的表时,你就必须尽快来处理 statement 产生的result set。

MySQL提供了一个可选的方案,即基于游标的 streaming。与逐行扫描不同的是它可以一次性读取多行数据。要使用这种方式,你需要将 useCursorFetch 设置为true,然后调用 setFetchSize 方法来设置你希望一次获取的行数:

emmm~,感觉没啥好补充的了。如果内存够大就没必要这么麻烦,直接默认就好了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值