Mysql-Java批量插入处理内存不足错误

时间:2013-02-26 11:20:32

标签: java mysql

我想问一下,在进行批量插入时处理OutOfMemoryError是否正常?

我正在使用以下代码在mysql中批量插入:

try
{
    Connection con = null;
    PreparedStatement ps = null;

    con = Manager.getInstance().getConnection();
    ps = con.prepareStatement("INSERT INTO" + 
    " movie_release_date_pushed_to_subscriber"
    + "(movie_id,cinema_id,msisdn,sent_timestamp)VALUES(?,?,?,?)");

    for (String msisdn : subscriberBatch)
    {
        try
        {
            ps.setInt(1, movieToBeReleased.getMovieId());
            ps.setInt(2, movieToBeReleased.getCinemaId());
            ps.setString(3, msisdn);
            ps.setTimestamp(4, new java.sql.Timestamp(new Date().getTime()));
            ps.addBatch();
        }
        catch (OutOfMemoryError oome)
        {
            ....
            ps.executeBatch();
        }
    }

    ps.executeBatch();
}
catch (Throwable e)
{
    ....
}
finally
{
    try
    {
        Manager.getInstance().close(ps);
        if (con != null)
        {
            con.close();
        }
    }
    catch (Throwable e)
    {
        ....
    }
}

注意:欢迎任何类型的建议/推荐,

2 个答案:

答案 0 :(得分:5)

没有正常。而你的捕获处理程序完全无效。捕捉OOME不会奇迹般地解决其根本原因 - 程序记忆耗尽。在运行时已尽最大努力回收内存并失败后,您会收到错误。你不应该试图在那时执行代码,你甚至可能无法记录消息!

如果您认为您的批处理声明可能导致OOME出于某种原因,那么您应该:

  • 将批处理周期分解为较小的“桶”
  • 为程序提供更多可用内存

答案 1 :(得分:2)

如果获得OutOfMemoryError,尝试执行批处理是没有意义的。但是,您可以使用INSERT替换INSERT IGNORE INTO查询,如果是OOME,请让用户在重新启动JVM后再次运行批处理。

如果主键已经存在于表中,那么INSERT IGNORE INTO将执行的操作不会运行插入,因此您的批处理将从崩溃应用程序的位置恢复。

但是,我必须警告你,这可能是一种非常肮脏的方法来规避这种情况。