NutzCN Logo
问答 使用fastInsert的时候NutDaoRunner140行报NPE
发布于 2165天前 作者 laizhiming 1922 次浏览 复制 上一个帖子 下一个帖子
标签:

使用的Nutz 1.r.66版本jar,数据源连接池用的druid-1.1.11。
在使用dao.fastInsert插入数据的时候,总是插入第七十几条的时候就报异常(NutDaoRunner140行报NPE),然后看了源码的注释【// 高并发时,从数据库连接池获取连接就已经抛错误,所以conn可能为null的】,表示比较蒙圈,就单线程再执行,不存在高并发呢,不知可有解决办法吗?或者避坑方式。

void org.nutz.dao.impl.sql.run.NutDaoRunner._runWithoutTransaction(DataSource dataSource, ConnCallback callback)
    public void _runWithoutTransaction(DataSource dataSource, ConnCallback callback) {
        Connection conn = null;
        // 开始一个连接
        try {
            conn = selectDataSource(null, dataSource, callback).getConnection();
            // 开始真正运行
            runCallback(conn, callback);
            // 完成提交
            if (!conn.getAutoCommit())
                conn.commit();
        }
        // 异常回滚
        catch (Exception e) {
            try {
                if (conn != null) // 高并发时,从数据库连接池获取连接就已经抛错误,所以conn可能为null的
                    conn.rollback();
            }
            catch (Exception e1) {}// TODO 简单记录一下?
            if (e instanceof DaoException)
                throw (DaoException)e;
            throw new DaoException(e);
        }
        // 保证释放资源
        finally {
            if (null != conn) {
                // 关闭链接
                try {
                    conn.close();
                }
                catch (SQLException closeE) {
                    if (log.isWarnEnabled())
                        log.warn("Fail to close connection!", closeE);
                }
            }
        }
    }
11 回复

贴一下你的代码

之前配置的aop.js是在有事务的情况下执行的,【void org.nutz.dao.impl.sql.run.NutDaoExecutor._runPreparedStatement(Connection conn, DaoStatement st, Object[][] paramMatrix) throws SQLException,】,以为是事务问题导致的,后来改成非事务模式,

之前配置的aop.js是在有事务的情况下执行的,【void org.nutz.dao.impl.sql.run.NutDaoExecutor._runPreparedStatement(Connection conn, DaoStatement st, Object[][] paramMatrix) throws SQLException,line:299】也是conn为null了,以为是事务问题导致的,后来改成非事务模式。

代码在客户这边内网,不方便贴出来。
我就说一下过程,伪代码如下:

List<Record> list = new ArrayList<Record>();
for(...){
    Record record = Record.create();
    record.put("a", "aval");
    record.put("b", "bval");
    list.add(record);
}
list.get(0).put(".table", "tablea");
dao().fastInsert(list);

那把连接池改大吧

连接池改大了没用,dao().fastInsert(list)的list.size()==1的时候,即一次fastInsert只插入1条的时候,也报错。
现在的需求就是有个几万条的数据,想组装后分批insert到表中。

翻了翻代码, 看上去不是140行的问题呀, 要不你把报错日志贴一下

应该是其他地方空指针了

我仔细检查一下别人写的代码吧,因为我按照伪代码的方式,自己按照他写的代码生成的insert SQL语句,自己组装Record,生成100W行数据,循环100次,每次fastInsert数据1W行,也没有报错。
我看他代码是很多查询,最后根据查询结果去组装Record进行insert。
先谢谢兽总的秒回,我估计八九不离十成是代码的逻辑有问题。

问题找到了,是因为刚好在第70多行数据的时候存在record.put("xxxx", null),导致preparedStatement.setString的时候NPE了。
用Strings.sBlank()处理一下就可以了。

添加回复
请先登陆
回到顶部