What is the best way to roll back () instruction execution failure in Java 8?

I am writing a transaction with Java 8. At first, my code was like that.

try (Connection conn = DAOUtil.getConnection();
     PreparedStatement ps = conn.prepareStatement(addSubscriptionSql)) {
    conn.setAutoCommit(false);
    //do work
    conn.commit();
} catch (SQLException e) {
    e.printStackTrace(); //handle error
}

But since I have to roll back in case of a transaction failure, I had to change the code as follows. Pay attention to two blocks try.

try (Connection conn = DAOUtil.getConnection()) {
    try (PreparedStatement ps = conn.prepareStatement(addSubscriptionSql)) {
        conn.setAutoCommit(false);
        //do work
        conn.commit();
    } catch (SQLException e) {
        conn.rollback();
        e.printStackTrace(); //handle error
    }
} catch (SQLException e) {
    e.printStackTrace(); //handle error
}

My question is: is there a better (I mean simpler) way to do this? Can I achieve this with a single try block?

+4
source share
2 answers

you can use

try(Connection conn = DAOUtil.getConnection();
    PreparedStatement ps = conn.prepareStatement(addSubscriptionSql);
    AutoCloseable finish = conn::rollback) {

    conn.setAutoCommit(false);
    //do work
    conn.commit();
}

This will always cause rollback(), but upon successful completion, the commit()rollback will become no-op, since it resets the state before that after the last successful completion commit()...

AutoCloseable Exception, . , :

interface SQLCloseable extends AutoCloseable {
    @Override public void close() throws SQLException;
}

...

try(Connection conn = DAOUtil.getConnection();
    PreparedStatement ps = conn.prepareStatement(addSubscriptionSql);
    SQLCloseable finish = conn::rollback) {

    conn.setAutoCommit(false);
    //do work
    conn.commit();
}

SQLException.

rollback(), , :

boolean[] success = { false };
try(Connection conn = DAOUtil.getConnection();
    PreparedStatement ps = conn.prepareStatement(addSubscriptionSql);
    SQLCloseable finish = () -> { if(!success[0]) conn.rollback(); }) {

    conn.setAutoCommit(false);
    //do work
    conn.commit();
    success[0] = true;
}

reset , :

try(Connection conn = DAOUtil.getConnection();
    PreparedStatement ps = conn.prepareStatement(addSubscriptionSql);
    SQLCloseable finish = () -> { if(!conn.getAutoCommit()) conn.rollback(); }) {

    conn.setAutoCommit(false);
    //do work
    conn.commit();
    conn.setAutoCommit(true);
}
+7

try?

, conn catch try-with-resources. PreparedStatement conn.rollback(), try try-with-, conn (.. try PreparedStatement).

+5

Source: https://habr.com/ru/post/1661836/


All Articles