1

我想问一下,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)
    {
        ....
    }
}

注意:欢迎任何形式的建议/推荐,

4

2 回答 2

5

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

如果您出于某种原因觉得您的批处理语句可能会导致 OOME,那么您应该:

  • 将批处理周期分解为更小的“桶”
  • 为程序提供更多内存
于 2013-02-26T11:25:32.190 回答
2

如果你得到一个OutOfMemoryError. 但是,您可以将INSERT查询替换INSERT IGNORE INTO为 OOME,如果出现 OOME,请要求用户在重新启动 JVM 后再次运行批处理。

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

但是,我将不得不警告您,这可能是规避这种情况的一种非常肮脏的方式。

于 2013-02-26T11:27:53.953 回答