Драйвер JDB C MySql возвращает неправильное значение после долгой работы - PullRequest
0 голосов
/ 11 апреля 2020

У меня есть MySQL дБ, и у меня есть проблема с двумя таблицами с именами product и product_older. Они имеют одинаковую структуру и строки таблицы продуктов, которые копируются в product_older один раз в день. Вот их структура:

+-----------------------+---------------+------+-----+-------------------+----------------+
| Field                 | Type          | Null | Key | Default           | Extra          |
+-----------------------+---------------+------+-----+-------------------+----------------+
| id                    | int(11)       | NO   | PRI | NULL              | auto_increment |
| price                 | decimal(18,2) | YES  |     | NULL              |                |
| price_older           | decimal(18,2) | YES  |     | NULL              |                |
+-----------------------+---------------+------+-----+-------------------+----------------+

У меня проблема только с полем price_older. Моя программа обновляет значения таблицы продуктов для более чем 3 миллионов данных. Поле price_older каждый раз принимает значение из price столбца product_older. Вот метод, который я использую price_older:

private double getOlderPrice(int id) {
    double price_older = 0.0d;
    try {
        String query = tools.getQuery("select price from product_older where id=?")
            .replace("?", String.valueOf(id));            
        com.mysql.jdbc.Connection connection = (Connection) DriverManager.getConnection(db_url, username, password);
        preparedStatement = (PreparedStatement) connection.prepareStatement(query);
        ResultSet resultSet = preparedStatement.executeQuery();
        if (resultSet.next()) {
            price_older = resultSet.getDouble(1);
        }
    } catch (SQLException e) {
        ..... // error log
    } finally {
       .... //close the prepared statement
    }
    return price_older;
}

И я использую это значение price_older, чтобы создать PriceList объект для каждого продукта, затем я использовал этот список для обновления таблицы продуктов. Вот мой код обновления: (тот же connection объект, который используется здесь с методом getOlderPrice.)

private void dbUpdate() throws SQLException {

    String query = "update product set price=?, price_older=? where id=?";

    try (com.mysql.jdbc.Statement statement = (Statement) connection.createStatement();
        com.mysql.jdbc.PreparedStatement updateStatement = (PreparedStatement) connection.prepareStatement(query)) {

        connection.setAutoCommit(false);

        int batchIndex = 0;

        for (UpdatePrice price : priceList) {

            if (price.getPrice() == null) {
                updateStatement.setNull(1, Types.DECIMAL);
            } else {
                updateStatement.setDouble(1, price.getPrice());
            }
            updateStatement.setDouble(2, price.getOlderPrice());
            updateStatement.setInt(3, price.getID());

            updateStatement.addBatch();

            batchIndex++;
            if (batchIndex % limitedBatchSize == 0) {
                updateStatement.executeBatch();
                connection.commit();
            }
        }

        updateStatement.executeBatch();
        connection.commit();
        connection.setAutoCommit(true);

        priceList.clear();
    }
}

Вот проблема; Он работает нормально в большинстве случаев, но примерно раз в ~ 30 дней он обновляет old_price с неправильным значением, и это неправильное значение обычно принадлежит другому продукту в БД, и когда он обновляет столбец с неправильным значением, ошибки не возникает журнал, потому что он выглядит нормально.

И для моего соединения rewriteBatchedStatements установлено значение true.

Как это может быть? Если есть ошибка, почему она работает нормально большую часть времени и как нет проблем со столбцом price? Если нет, почему он обновляет значение не в том месте?

Меня искали более недели, но результата нет, а также я не могу воспроизвести ошибку, и это дает меньше возможностей быть уверенным, где проблема на самом деле.

...