Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JDBC and Oracle conn.commit and conn.setAutocommit not working properly

I have made a DBManager class as shown below

public class DBManager {


      public static String DRIVER = "oracle.jdbc.driver.OracleDriver";
      public static String URL = "jdbc:oracle:thin:@//localhost:1521/DB";
      public static String USERNAME = "afsweb";
      public static String PASSWORD = "afsweb";
      public static String DOCDBUSERNAME = "docdb";
      public static String DOCDBPASSWORD = "docdb";
      public static int PORT = 1521;

    //static Logger log = Logger.getLogger(ExcelDBManager.class.getName());
    public static Connection getConnection(String url ,String username, String password){
    try {
        Class.forName(DRIVER);
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Connection con = null;
    try {
        con = DriverManager.getConnection(url,username,password);
        con.setAutoCommit(false);
        } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

    }
    return con;
}

And i have method truncate rows in table

public static void truncate() throws SQLException{
        conn = DBManager.getConnection(DBManager.URL, DBManager.USERNAME, DBManager.PASSWORD);
        System.out.println(conn.getAutoCommit()  +"");
        Statement pstmnt = null;
        ResultSet rs = null;
        try{    
            pstmnt = conn.createStatement();
            pstmnt.executeQuery("truncate table bd_vehicles_temp_1");
            System.out.println("Query Executed");
        }
        catch(SQLException e){
            e.printStackTrace();
        }
        finally{
            try{
            if(rs !=null){
                rs.close();
            }
            if(pstmnt != null){
                pstmnt.close();
            }
            if(conn != null){
                conn.close();
            }
            }
            catch(SQLException e)
            {
                e.printStackTrace();
            }
        }
    }

Now i have not written conn.commit inside my truncate() method. Also i have setAutocommit to false. Even then the changes are reflected in database.

On Executing the above method i get output as

false
Query Executed

Which means my connections autocommit mode is false. Still the changes made by truncate method is reflected in database. What could be the possible reason ?? I am using Oracle Database.

Thanks in Advance !

like image 876
Abhishek Singh Avatar asked Aug 14 '13 13:08

Abhishek Singh


People also ask

How can you avoid auto commit mode in JDBC?

Explicit Transaction Management When Auto-Commit Is False We need to disable auto-commit mode when we want to handle transactions ourselves and group multiple SQL statements into one transaction. We do this by passing false to the connection's setAutoCommit method: connection. setAutoCommit(false);

How do I make auto commit to true?

This method accepts a boolean value as a parameter. If you pass true to this method it turns on the auto-commit feature of the database and, if you pass false to this method it turns off the auto-commit feature of the database. //Setting the auto commit on con. setAutoCommit(true); //Setting the auto commit off con.

Does JDBC automatically commit a transaction?

When a connection is created, it is in auto-commit mode. This means that each individual SQL statement is treated as a transaction and is automatically committed right after it is executed. (To be more precise, the default is for a SQL statement to be committed when it is completed, not when it is executed.

Why will you set auto commit mode to false?

When the autocommit mode is false, the JDBC driver will implicitly start a new transaction after each commit. If this method is called during a transaction, the transaction is committed.


4 Answers

TRUNCATE is a Data Definition Language (DDL) command which commits implicitly. It wouldn't have committed anything, had you used the DELETE statement instead.

// Deletes ALL Rows; No WHERE Clause
pstmnt.executeQuery("DELETE FROM bd_vehicles_temp_");

The reason TRUNCATE is a DDL statement is that it removes the table data directly without copying it into the Rollback Tablespace. That's why TRUNCATE is faster but cannot be rolled back.

EDIT : (Why my INSERTs are committing as well?)

That's because you're closing your Connection without calling Connection#rollback().

If a Connection is closed without an explicit commit or a rollback; JDBC does not mandate anything in particular here and hence the behaviour is dependent on the database vendor. In case of Oracle, an implict commit is issued.

It is strongly recommended that an application explicitly commits or rolls back an active transaction prior to calling the close method. If the close method is called and there is an active transaction, the results are implementation-defined.

SO, just rollback() your changes before closing your Connection in the finally block

pstmnt = conn.createStatement();

pstmnt.executeQuery("DELETE FROM bd_vehicles_temp_1");
System.out.println("Query Executed");

conn.rollback();
System.out.println("Changes rolled back");
like image 91
Ravi K Thapliyal Avatar answered Nov 04 '22 01:11

Ravi K Thapliyal


TRUNCATE TABLE basically doesn't allow commit/rollback in the normal way. As per this documentation:

Because a Truncate is DDL it issues a COMMIT before it acts and another COMMIT afterward so no rollback of the transaction is possible.

If you want to do this as part of a transaction, use DML instead - e.g. a normal DELETE FROM ... statement.

like image 32
Jon Skeet Avatar answered Nov 04 '22 01:11

Jon Skeet


Oracle truncate command is DDL and it issues commit implicitly. See http://docs.oracle.com/cd/E17952_01/refman-5.5-en/truncate-table.html

like image 25
Evgeniy Dorofeev Avatar answered Nov 04 '22 02:11

Evgeniy Dorofeev


Autocommit behavior depends on the underlying database you use. An unfortunately in your case Oracle's JDBC driver commits on close() by default.

like image 33
Juned Ahsan Avatar answered Nov 04 '22 01:11

Juned Ahsan