前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java大量数据加载时resultSetType参数的设置 TYPE_FORWARD_ONLY

java大量数据加载时resultSetType参数的设置 TYPE_FORWARD_ONLY

作者头像
10km
发布2019-05-25 22:44:37
3K0
发布2019-05-25 22:44:37
举报
文章被收录于专栏:10km的专栏

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433806

这两天的工作是将一1000万条数据库记录(10GB)加载到内存中,加载到500多万条记录的时候,就报了OOM(内存不足)。

解决了所有可能造成内存使用不当的外围问题后,再运行还是这个问题,无法加载全部数据。于是只好沉下心仔细研究了之前很少碰的底层访问数据库的代码(这部分代码是第三方的ORM软件通过模板生成的)。

代码语言:javascript
复制
    /**
     * Load each the elements using a SQL statement specifying a list of fields to be retrieved and dealt by action.
     * @param sql the SQL statement for retrieving
     * @param argList the arguments to use fill given prepared statement,may be null
     * @param fieldList table of the field's associated constants
     * @param startRow the start row to be used (first row = 1, last row = -1)//起始行号
     * @param numRows the number of rows to be retrieved (all rows = a negative number)//行数
     * @param action Action object for do something(not null)
     * @return the count dealt by action
     * @throws DAOException
     */
    public int loadBySqlForAction(String sql, Object[] argList, int[] fieldList,int startRow, int numRows,Action action) throws DAOException{
        PreparedStatement ps = null;
        Connection connection = null;
        try {
            //获取数据库连接
            connection = this.getConnection();
            //创建PreparedStatement 
            ps = connection.prepareStatement(sql,
                    1==startRow?ResultSet.TYPE_SCROLL_INSENSITIVE:ResultSet.TYPE_SCROLL_SENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);
            //填充PrepareStatement中的?占位符
            fillPrepareStatement(ps, argList);
            //执行PreparedStatement 
            return this.loadByPreparedStatement(ps, fieldList, startRow, numRows, action);
        } catch (DAOException e) {
            throw e;
        }catch (SQLException e) {
            throw new DataAccessException(e);
        } finally {
            this.getManager().close(ps);
            this.freeConnection(connection);
        }
    }

在创建PreparedStatement时,resultSetType参数设置的是TYPE_SCROLL_INSENSITIVETYPE_SCROLL_SENSITIVE,

这两个参数的共同特点是允许结果集(ResultSet)的游标可以上下移动。而默认的TYPE_FORWARD_ONLY参数只允许结果集的游标向下移动。

我加载这么大量的数据到内存过程中,只是顺序读取每一条记录,TYPE_FORWARD_ONLY就够了,游标用不着前后移动,于是将改为TYPE_FORWARD_ONLY,重新生成ORM代码,遂加载成功。

代码语言:javascript
复制
            ps = connection.prepareStatement(sql,
                    ResultSet.TYPE_FORWARD_ONLY,
                    ResultSet.CONCUR_READ_ONLY);

总结

如果PreparedStatement对象初始化时resultSetType参数设置为TYPE_FORWARD_ONLY,在从ResultSet(结果集)中读取记录的时,对于访问过的记录就自动释放了内存。而设置为TYPE_SCROLL_INSENSITIVETYPE_SCROLL_SENSITIVE时为了保证能游标能向上移动到任意位置,已经访问过的所有都保留在内存中不能释放。所以大量数据加载的时候,就OOM了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015年12月25日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档