java中调用多个oracle存储过程并保持数据一致性

Posted

技术标签:

【中文标题】java中调用多个oracle存储过程并保持数据一致性【英文标题】:Calling multiple oracle stored procedure in java and maintaining data consistency 【发布时间】:2012-10-08 10:25:57 【问题描述】:

此方法有一些我无法理解的问题,例如,如果层次结构中的任何过程调用引发异常,它不会回滚在之前的过程调用中所做的更改......请帮帮我

public synchronized boolean save(DTO dto) throws DAOException,IllegalArgumentException
           boolean retVal=false;
            boolean retVal1=false;
            boolean retVal2=false;
            boolean retVal5=true;
    try
                connection=dataSource.getConnection();
                connection.setAutoCommit(false);
                cstmt=connection.prepareCall("call PKG_ALL.PROC_MAIN(?,?,?)");

                cstmt.setString(1, "A");     cstmt.setString(2, "B");
                cstmt.registerOutParameter(3,Types.VARCHAR);

                ResultSet rs=cstmt.executeQuery();                  
                String ErrMsg=cstmt.getString(3);
                if(ErrMsg.equalsIgnoreCase("Record Inserted"))  retVal=true;
                else retVal=false;

        cstmt.close();

        cstmt1=connection.prepareCall("call PKG_ALL.PROC_CHILD1(?,?,?)");

                cstmt1.setString(1, "A");     cstmt1.setString(2, "B");
                cstmt1.registerOutParameter(3,Types.VARCHAR);

                ResultSet rs1=cstmt.executeQuery();                 
                String ErrMsg1=cstmt1.getString(3);
                if(ErrMsg1.equalsIgnoreCase("Record Inserted")) retVal1=true;
                else retVal1=false;

        cstmt1.close();

        if(strSerialNo!=null && strSerialNo.length > 0) // for a non-mandatory multirow in the form
          
            cstmt2=connection.prepareCall("call PKG_ALL.PROC_CHILD2(?,?,?)");
                for(int k=0;k<strSerialNo.length;k++)
                    
                        cstmt2.setString(1,"M");
                        cstmt2.setString(2,"I");
                        cstmt2.registerOutParameter(3,Types.VARCHAR);

                        ResultSet rs2=cstmt2.executeQuery();
                        String ErrMsg2=cstmt2.getString(3);
                        if(ErrMsg2.equalsIgnoreCase("Record Inserted")) retVal2=true;
                        else
                            
                                retVal5=false;
                                retVal2=false;
                                       
                     
            cstmt2.close();
           

        **if(retVal&&retVal1&&retVal5)**
                
                    retVal=true;
                    connection.commit();
                
                else
                
                    //connection.rollback();
                    retVal=false;
                
    
    catch(SQLException e)
            
                throw new DAOException(":"+e.getMessage());
            
            catch(Exception e)
            
                throw new DAOException(":"+e.getMessage());

            
            finally
            
                closeConnection(connection);
            
            return retVal;
   

【问题讨论】:

【参考方案1】:

如果层次结构中的任何过程调用引发异常,它不会回滚在先前过程调用中所做的更改

Ofc,您不要将回滚调用放在 catch SQLException 块中。仅当您的请求之一不工作且不引发异常时才调用回滚方法。

此外,您在执行请求后永远不会提交更改,因此当您来到调用 connection.rollback(); 的 else 语句时,您实际上没有什么可回滚的,因为没有任何内容被提交。

阅读this page,了解如何处理提交/回滚的基本示例。

【讨论】:

请告诉我丢失的代码会是什么样子..@alain.janinm @user1728387 你可以使用connection.commit();每次查询后。然后在 catch 块中添加 connection.rollback(); if(retVal&&retVal1&&retVal5)

以上是关于java中调用多个oracle存储过程并保持数据一致性的主要内容,如果未能解决你的问题,请参考以下文章

oracle数据库调用存储过程

从java调用oracle存储过程时在mybatis mapper中映射多个out参数

多线程调用oracle存储过程是不是并发执行?

Oracle如何创建存储过程和如何调用存储过程

Oracle DBMS 能否从 Java 存储过程调用返回 Java 对象?

请问如何用c++ 调用oracle存储过程?