2013-08-14 4 views
5

Ho fatto una classe DBManager come illustrato di seguitoJDBC e Oracle conn.commit e conn.setAutocommit non funziona correttamente

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; 
} 

e non ho metodo troncare le righe nella tabella

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(); 
      } 
     } 
    } 

Ora ho non scritto conn.commit all'interno del mio metodo truncate(). Inoltre ho impostato suAutocommit su false. Anche allora le modifiche si riflettono nel database.

Sulla L'esecuzione del metodo di cui sopra ottengo uscita come

false 
Query Executed 

Il che significa che il mio modo di connessioni autocommit è falso. Ancora le modifiche apportate dal metodo truncate si riflettono nel database. Quale potrebbe essere la possibile ragione ?? Sto usando Oracle Database.

Grazie in anticipo!

risposta

10

TRUNCATE è un comando DDL (Data Definition Language) che esegue il commit implicitamente. Non avrebbe commesso nulla, avevi usato l'istruzione DELETE.

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

La ragione TRUNCATE è una dichiarazione DDL è che rimuove i dati della tabella direttamente senza copiarlo nella rollback tablespace. Ecco perché TRUNCATE è più veloce ma non può essere ripristinato.

EDIT: (Perchè i miei inserti sono commettendo così?)

Ecco perché si sta chiudendo il tuo Connection senza chiamare Connection#rollback().

Se un connessione è chiuso senza un esplicito commettere o un rollback ; JDBC non impone nulla in particolare qui e quindi il comportamento dipende dal fornitore del database. In caso di Oracle, viene emesso un commit implicito.

E 'fortemente raccomandato che un'applicazione impegna esplicitamente o il rollback di una transazione attiva prima di chiamare il metodo close. Se viene chiamato il metodo close e c'è una transazione attiva, i risultati sono definiti dall'implementazione.

Così, proprio rollback() le modifiche prima di chiudere il collegamento nel finalmente blocco

pstmnt = conn.createStatement(); 

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

conn.rollback(); 
System.out.println("Changes rolled back"); 
+0

Lo stesso è il risultato per comando di inserimento anche –

+0

@AbhishekSingh Ho aggiunto la mia risposta come aggiornamento alla mia risposta. Per favore guarda. –

4

TRUNCATE TABLE fondamentalmente non consente commit/rollback in modo normale.Come da this documentation:

Perché un Tronca è DDL è un COMMIT prima agisce e un altro COMMIT dopo quindi non rollback della transazione è possibile.

Se si desidera eseguire ciò come parte di una transazione, utilizzare invece DML, ad es. una normale dichiarazione DELETE FROM ....

+0

Ottengo gli stessi risultati per il comando insert –

+0

@AbhishekSingh: Insert? Pensavo che stavi cercando di cancellare? –

+0

Questo è uno scenario diverso in cui mi trovo ad affrontare lo stesso problema per l'inserimento di righe –

2

Il comportamento di autocommit dipende dal database sottostante che si utilizza. Sfortunatamente nel tuo caso il driver JDBC di Oracle si commette su close() per impostazione predefinita.

+0

Sei sicuro che questa sia la ragione? Ottengo lo stesso risultato anche se inserisco! –

+0

@AbhishekSingh Per quanto ne so, il flag autocommit non cambierà nulla per il driver oracle, poiché la connessione viene commessa non appena viene chiusa. –

+0

Qualche fonte per questo? Perché in quel caso dovrò fare conn.rollback! –