Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JDBC: Does call to rollback() method have effect only if call to commit() method does not succeed?

I am new to Java JDBC, and developed a small database application. I am learning from O'Reilly - Database Programming with JDBC and Java 2nd Edition.

Does con.rollback() have effect only ifcon.commit does not succeed?

I expected that calling con.rollback() has its effect even if con.commit() succeeded. In other words, utilizing it as an "Undo" action.

I tried calling con.rollback() after con.commit() succeeded, but it is not working as expected. So is it alright/expected?

This example is from the book I mentioned above:

The call to con.rollback() is commented out. It is near the end before con.close(). I tried uncommenting it and running it. However, con.rollback() doesn't roll things back after con.commit() succeeded.

import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class UpdateLogic
{

    public static void main(String args[])
    {
        Connection con = null;

        try
        {
            String driver = "com.mysql.jdbc.Driver";
            Class.forName(driver).newInstance();
            String url = "jdbc:mysql://localhost:3306/Company";
            Statement s;
            con = DriverManager.getConnection(url, "root", "");
            con.setAutoCommit(false); // make sure auto commit is off!
            s = con.createStatement();// create the first statement
            s.executeUpdate("INSERT INTO employee VALUES ('1', 'employee 1', '22','00-1234' )");

            s.close(); // close the first statement
            s = con.createStatement(); // create the second statement
            s.executeUpdate("INSERT INTO employee VALUES ('2', 'employee 2', '21','00_4321' )");

            con.commit(); // commit the two statements
            System.out.println("Insert succeeded.");
            s.close(); // close the second statement
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex)
        {
            Logger.getLogger(UpdateLogic.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException e)
        {
            if (con != null)
            {
                try
                {
                    con.rollback();
                } // rollback on error
                catch (SQLException i)
                {
                }
            }
            e.printStackTrace();
        } finally
        {
            if (con != null)
            {
                try
                {
                  //con.rollback();
                    con.close();
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}
like image 319
Saleh Feek Avatar asked Feb 22 '13 19:02

Saleh Feek


2 Answers

When you call commit(), you complete/close the current transaction. Thus, since rollback() undoes any changes in the current transaction (as per the javadoc), it will effectively do nothing.

like image 177
jtahlborn Avatar answered Oct 07 '22 16:10

jtahlborn


Is con.rollback() has effect only if con.commit not succeeded?

YES And It also has effect if you call it before con.commit . And prerequisite is that autocommit mode of connection should be false using con.setAutoCommit(false)
Any transaction that you make in database using DML SQL queries using JDBC with con.setAutoCommit(false) is not commited to database until con.commit() is called. The latest commited transaction that you make in database acts as the savepoint for that connection. When you call con.rollback() all transaction that you have done after that savepoint is undone. Also if some exception occurs while calling con.commit(), it means that transactions are not saved in database. It is a good practice to call con.rollback() in catch statement if con.commit() fails.

like image 43
Vishal K Avatar answered Oct 07 '22 14:10

Vishal K