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 !
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);
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.
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.
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.
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");
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.
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
Autocommit behavior depends on the underlying database you use. An unfortunately in your case Oracle's JDBC driver commits on close() by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With