调用存储过程后建议提交/自动提交或回滚

时间:2015-12-18 15:27:27

标签: java sql-server stored-procedures jdbc commit

在Java中调用存储过程并不常见,所以我担心在线有关该过程的信息有点受限。通常我在开头使用connection.setAutoCommit(false);,最后使用常规DB-Updates使用connection.commit();

在我没有使用c.commit();行之前,由于这个函数是通过Ajax调用的,我在FireBug中看到Ajax-Request永远不会完成,这使我添加了ps.setQueryTimeout(99);行。

现在我调用存储过程的方法如下所示:

private void callProcedure(int customer, int user, String stmt) {
        Connection c = null;
        PreparedStatement ps = null;

        try {
            c = ConnectionTools.getConnection();
            c.setAutoCommit(false);
            //"EXEC CustomerUpdate ?, ?";
            ps = c.prepareStatement(stmt);
            ps.setEscapeProcessing(true);
            ps.setQueryTimeout(99);
            ps.setInt(1, customer);
            ps.setInt(2, user);
            ps.executeUpdate();
            c.commit();

        } catch (NamingException | SQLException ex) {

            if (c != null) {
                try {
                    c.rollback();
                } catch (SQLException ex1) {  
                    Logger.getLogger(CustomerProcedures.class.getName()).log(Level.SEVERE, null, ex1);
                }
            }
            Logger.getLogger(CustomerProcedures.class.getName()).log(Level.INFO, "SQL: {0}; {1}; {2}", new Object[]{stmt, customer, user});
            Logger.getLogger(CustomerProcedures.class.getName()).log(Level.SEVERE, null, ex);

        } finally {
            ConnectionTools.disconnect(ps, c);
        }
    }

从与我的问题相关的材料中有一个例子,但是回滚,而不是提交:calling PLSQL procedure from Java - 这个例子看起来很好,因为只有一个与问题本身无关的小错误。在我的印象中,设置conn.setAutoCommit(false);似乎很好。

在另一个很少引起注意的例子中,没有使用过类似的内容:Java: Calling a stored procedure in an oracle database

在其他来源中我也找不到多少。 Coderanch进行了简短的讨论,但在我的存储过程中没有提交(http://www.coderanch.com/t/621006/java/java/commit-written-procedures-called-Java

在官方文档中,提交问题也没有太多关注:https://docs.oracle.com/javase/tutorial/jdbc/basics/storedprocedures.html 他们建议您使用prepareCall代替prepareStatementexecute代替executeUpdate

cs = this.con.prepareCall("{call RAISE_PRICE(?,?,?)}");
cs.setString(1, coffeeNameArg);
cs.setFloat(2, maximumPercentageArg);
cs.registerOutParameter(3, Types.NUMERIC);
cs.setFloat(3, newPriceArg);

cs.execute();

只有:

  

注意:与Statement对象一样,要调用存储过程,您可以   调用execute,executeQuery或executeUpdate取决于多少   过程返回的ResultSet对象。但是,如果你不确定   过程返回多少个ResultSet对象,调用execute。

但到目前为止没有任何承诺...

0 个答案:

没有答案