javamysqljdbcrollbackautocommit

Connection.rollback() doesn't work in Java


I wrote this function to easily populate my database(mySQL) :

public boolean addItems(Connection con) throws SQLException {
    try {
        con.setAutoCommit(false);
        String[] brands = { "Honda", "BMW", "Mercedes Benz" };
        String[] optional = { "acciaio", "alluminio", "carbonio", "titanio" };
        Statement statement = con.createStatement();
        for (int i = 0; i < brands.length; i++) {
            for (int j = 0; j < optional.length; j++) {
                statement.executeUpdate("INSERT INTO chassis (idUnit, brand, material, availableItems) VALUES (1, '" + brands[i] + "', '" + optional[j] + "', 20)");
                statement = Condb.replaceStatement(statement);
                ResultSet rs = statement.executeQuery("SELECT * FROM chassis WHERE brand = '" + brands[i] + "' AND material = '" + optional[j] + "'");
                while (rs.next()) {
                    statement = Condb.replaceStatement(statement);
                    statement.executeUpdate("INSERT INTO product_code (unitName, productCode, brand, optional) VALUES ('chassis', " + rs.getInt("productCode") + ", '" + brands[i] + "', '" + optional[j] + "')");
                    con.commit();
                }
            }
        }
        return true;
    } catch (Exception exception) {
        exception.printStackTrace();
        con.rollback();             
        return false;
    }
}

But it adds one record in 'chassis' table (first update), then it doesn't enter in the while loop ('productCode' field is an auto increment field, so I need to take it from chassis table in order to add a record in 'product_code' table). After this, it increase the j variable, executes the update in the chassis table, enters in the while loop and at the update (in the loop) it throws a SQLException

Operation not allowed after ResultSet closed

But it never executes the rollback. So I have records in my chassis table, but product_code table is empty. This is my replaceStatement function :

public static Statement replaceStatement(Statement stmt) {
    try {
        stmt.close();
        Statement statement = Condb.initializeDatabase().createStatement();
        return statement;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Anyone can help me solve this issue?


Solution

  • You can't commit and then request a rollback. For a connection that you use with plain JDBC either make a single commit in the end or trigger a rollback if some statements fails.

    So con.commit(); should be placed just before return true

    Otherwise you can handle manualy multiple transactions inside your loops following this answer https://stackoverflow.com/a/47482143/7237884