2013-08-14 3 views
5

मैं एक DBManager वर्ग के रूप में नीचेJDBC और Oracle conn.commit और conn.setAutocommit काम नहीं कर ठीक से

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

दिखाया बना दिया है और मुझे विधि है तालिका में पंक्तियों काटना

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

अब मेरे पास है मेरे truncate() विधि के अंदर conn.commit लिखा नहीं है। इसके अलावा मैंने गलत करने के लिए सेटऑटोकॉमिट सेट किया है। फिर भी परिवर्तन डेटाबेस में परिलक्षित होते हैं।

उपरोक्त विधि निष्पादित पर मैं के रूप में

false 
Query Executed 

जिसका मतलब है मेरी कनेक्शन autocommit मोड गलत है उत्पादन मिलता है। अभी भी truncate विधि द्वारा किए गए परिवर्तन डेटाबेस में परिलक्षित होता है। संभावित कारण क्या हो सकता है ?? मैं ओरेकल डेटाबेस का उपयोग कर रहा हूँ।

अग्रिम में धन्यवाद!

उत्तर

10

TRUNCATE एक डेटा परिभाषा भाषा (डीडीएल) कमांड है जो पूर्ण रूप से कार्य करता है। यह कुछ भी नहीं किया होता, क्या आपने इसके बजाय DELETE कथन का उपयोग किया था।

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

कारण TRUNCATE एक DDL कथन है कि यह तालिका डेटा सीधे रोलबैक तालिका स्थान में कॉपी किए बिना ही निकाल देता है। यही कारण है कि TRUNCATE तेज है लेकिन वापस लुढ़का नहीं जा सकता है।

संपादित: (क्यों मेरी आवेषण के साथ-साथ करने से कर रहे हैं?)

क्योंकि आप Connection#rollback() बुला के बिना अपने कनेक्शन बंद करने कर रहे हैं यही कारण है कि।

एक कनेक्शन बिना एक स्पष्ट प्रतिबद्ध या बंद है, तो एक रोलबैक; जेडीबीसी विशेष रूप से यहां कुछ भी जरूरी नहीं है और इसलिए व्यवहार डेटाबेस विक्रेता पर निर्भर है। ओरेकल के मामले में, प्रतिबद्ध जारी किया गया है।

यह है दृढ़ता से कि एक आवेदन स्पष्ट करता है या वापस पूर्व करीब विधि बुला के लिए कोई सक्रिय लेनदेन रोल की सिफारिश की। अगर करीबी विधि को बुलाया जाता है और एक सक्रिय लेनदेन होता है, तो परिणाम कार्यान्वयन-परिभाषित होते हैं।

अतः, बस rollback() अपने परिवर्तनों अंत में ब्लॉक

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

सम्मिलित करने के लिए भी परिणाम है –

+0

@ अभिषेकसिंह मैंने अपने उत्तर में एक अद्यतन के रूप में अपनी प्रतिक्रिया जोड़ दी है। कृपया एक नज़र डालें। –

4

TRUNCATE TABLE में अपने कनेक्शन बंद करने से पहले मूल रूप से सामान्य तरीके से प्रतिबद्ध/रोलबैक अनुमति नहीं है।this documentation के अनुसार:

क्योंकि एक काटना यह जारी करता है एक COMMIT से पहले यह काम करता है और एक और बाद में COMMIT इसलिए लेन-देन का कोई रोलबैक संभव है DDL है।

यदि आप इसे लेनदेन के हिस्से के रूप में करना चाहते हैं, तो इसके बजाय डीएमएल का उपयोग करें - उदा। एक सामान्य DELETE FROM ... कथन।

+0

मुझे सम्मिलित करने के लिए एक ही परिणाम मिलते हैं –

+0

@ अभिषेकसिंह: सम्मिलित करें? मैंने सोचा था कि आप हटाने की कोशिश कर रहे थे? –

+0

यह एक अलग परिदृश्य है जहां मुझे पंक्तियों को सम्मिलित करने के लिए एक ही समस्या का सामना करना पड़ता है –

2

Autocommit व्यवहार आपके द्वारा उपयोग किए जाने वाले अंतर्निहित डेटाबेस पर निर्भर करता है। दुर्भाग्य से आपके मामले में ओरेकल का जेडीबीसी चालक डिफ़ॉल्ट रूप से करीब() पर काम करता है।

+0

क्या आप वाकई यही कारण हैं? अगर मैं सम्मिलित करता हूं तो भी मुझे वही परिणाम मिलता है! –

+0

@ अभिषेकसिंह जहां तक ​​मुझे पता है, autocommit ध्वज ऑरैकल ड्राइवर के लिए कुछ भी नहीं बदलेगा, क्योंकि कनेक्शन बंद होने पर ही किया जाता है। –

+0

उसके लिए कोई स्रोत? क्योंकि उस मामले में मुझे conn.rollback करना होगा! –

संबंधित मुद्दे