JDBC和Oracle conn.commit和conn.setAutocommit无法正常工作

Abh*_*ngh 6 java connection jdbc oracle11g

我已经创建了一个DBManager类,如下所示

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;
}
Run Code Online (Sandbox Code Playgroud)

我有方法截断表中的行

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();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在我还没有在truncate()方法中编写conn.commit.我也将setAutocommit设为false.即便如此,这些变化也反映在数据库中.

在执行上述方法时,我输出为

false
Query Executed
Run Code Online (Sandbox Code Playgroud)

这意味着我的连接自动提交模式为false.截断方法所做的更改仍反映在数据库中.可能的原因是什么?我正在使用Oracle数据库.

提前致谢 !

Rav*_*yal 10

TRUNCATE是一种隐式提交的数据定义语言(DDL)命令.如果您使用该DELETE语句,它就不会提交任何内容.

// Deletes ALL Rows; No WHERE Clause
pstmnt.executeQuery("DELETE FROM bd_vehicles_temp_");
Run Code Online (Sandbox Code Playgroud)

原因TRUNCATE是DDL语句是直接删除表数据而不将其复制到Rollback表空间.这就是为什么TRUNCATE更快但无法回滚的原因.

编辑 :(为什么我的INSERTs也提交?)

那是因为你在没有调用Connection#rollback()的情况下关闭了你的Connection.

如果在没有显式提交回滚的情况下关闭Connection ; JDBC并不特别强制要求任何内容,因此行为取决于数据库供应商.对于Oracle,会发出隐含提交.

强烈推荐该应用程序显式提交或调用Close方法之前回滚活动事务.如果调用close方法并且存在活动事务,则结果是实现定义的.

所以,只需在finally块中rollback()关闭Connection之前进行更改

pstmnt = conn.createStatement();

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

conn.rollback();
System.out.println("Changes rolled back");
Run Code Online (Sandbox Code Playgroud)