2013-08-14 31 views
5

Tôi đã thực hiện một lớp DBManager như hình dưới đâyJDBC và Oracle conn.commit và conn.setAutocommit không hoạt động đúng

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

Và tôi có phương pháp cắt xén hàng trong bảng

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

Bây giờ tôi có không viết conn.commit bên trong phương thức truncate() của tôi. Ngoài ra tôi có setAutocommit để sai. Thậm chí sau đó các thay đổi được phản ánh trong cơ sở dữ liệu.

On Thi công các phương pháp trên tôi nhận được đầu ra như

false 
Query Executed 

Có nghĩa là chế độ kết nối autocommit của tôi là sai. Các thay đổi được thực hiện bằng phương pháp cắt ngắn được phản ánh trong cơ sở dữ liệu. Điều gì có thể là lý do có thể? Tôi đang sử dụng cơ sở dữ liệu Oracle.

Cảm ơn bạn đã nâng cao!

Trả lời

10

TRUNCATE là lệnh Ngôn ngữ định nghĩa dữ liệu (DDL) cam kết hoàn toàn. Nó sẽ không có cam kết gì cả, thay vào đó bạn đã sử dụng câu lệnh DELETE.

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

Lý do TRUNCATE là một tuyên bố DDL là nó loại bỏ các dữ liệu bảng trực tiếp mà không cần sao chép nó vào Rollback Tablespace. Đó là lý do tại sao TRUNCATE nhanh hơn nhưng không thể khôi phục được.

EDIT: (Tại sao Phụ trang của tôi đang cam kết không?)

Đó là bởi vì bạn đang đóng cửa của bạn kết nối mà không gọi Connection#rollback().

Nếu một kết nối bị đóng mà không có một rõ ràng cam hoặc một rollback; JDBC không ủy nhiệm bất cứ điều gì đặc biệt ở đây và do đó hành vi này phụ thuộc vào nhà cung cấp cơ sở dữ liệu. Trong trường hợp của Oracle, một cam kết cam kết được cấp.

Đó là được khuyến nghị mạnh mẽ rằng ứng dụng cam kết rõ ràng hoặc cuộn lại giao dịch đang hoạt động trước khi gọi phương thức đóng. Nếu phương thức đóng được gọi và có một giao dịch hoạt động, kết quả sẽ được xác định thực hiện.

SO, chỉ rollback() thay đổi của bạn trước khi đóng cửa của bạn kết nối trong cuối cùng khối

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

Kết quả tương tự cho lệnh chèn cũng –

+0

@AbhishekSingh Tôi đã thêm câu trả lời của mình làm cập nhật cho câu trả lời của mình. Xin vui lòng, có một cái nhìn. –

4

TRUNCATE TABLE về cơ bản không cho phép cam/rollback theo cách thông thường.Theo this documentation:

Vì cắt ngắn là DDL phát hành COMMIT trước khi nó hoạt động và một COMMIT khác sau đó nên không thể hoàn lại giao dịch.

Nếu bạn muốn thực hiện điều này như là một phần của giao dịch, hãy sử dụng DML thay thế - ví dụ: tuyên bố thông thường DELETE FROM ....

+0

Tôi nhận được kết quả tương tự cho lệnh chèn –

+0

@AbhishekSingh: Chèn? Tôi nghĩ bạn đang cố gắng xóa? –

+0

Đây là một kịch bản khác nhau mà tôi phải đối mặt với cùng một vấn đề cho chèn hàng –

2

Hành vi tự động phụ thuộc vào cơ sở dữ liệu cơ bản bạn sử dụng. Thật không may trong trường hợp của bạn, trình điều khiển JDBC của Oracle cam kết đóng() theo mặc định.

+0

Bạn có chắc đây là lý do không? Tôi nhận được kết quả tương tự ngay cả khi tôi chèn! –

+0

@AbhishekSingh Theo như tôi biết, cờ autocommit sẽ không thay đổi bất cứ điều gì cho trình điều khiển oracle, như kết nối được cam kết ngay sau khi nó được đóng lại. –

+0

Bất kỳ nguồn nào cho điều đó? Bởi vì trong trường hợp đó tôi sẽ phải làm conn.rollback! –

Các vấn đề liên quan