【问题标题】:commit() should be called before retrieving the values for out parameters?在检索 out 参数的值之前应该调用 commit() 吗?
【发布时间】:2017-11-10 15:59:15
【问题描述】:

在编写 java JDBC 代码来调用存储过程时,我正在使用 con.setAutoCommit(false); 我的问题是以下方法有什么区别:

方法一:

        con = DBConnection.getConnection();
        con.setAutoCommit(false);
        stmt= con.prepareCall("{call updateEmp(?,?,?,?,?,?)}");
        stmt.setInt(1, id);
        stmt.setString(2, name);
        stmt.setString(3, role);            
        stmt.registerOutParameter(6, java.sql.Types.VARCHAR);

        stmt.executeUpdate();
        con.commit();
        //read the OUT parameter AFTER commit
        String result = stmt.getString(6);

或方法 2:

        // Read the OUT parameter BEFORE commit
        String result = stmt.getString(6);
        con.commit();

【问题讨论】:

  • 不同的是,commit 是向下一行...
  • @alfasin 有时幽默是个好主意。 +1

标签: java sql oracle procedure autocommit


【解决方案1】:

我认为这取决于您调用的存储过程是否自己提交。我希望有一个接受参数的更新过程,并设置参数以在内部进行提交或回滚。

在这种情况下,调用 setAutoCommit(true) 或调用 con.commit() 将不起作用,并且无论何时调用 stmt.getString(6),out 参数都会有一个值。如果存储过程本身没有提交,如果您在调用 stmt.getString(6) 之后调用 con.commit(),我希望您的 out 参数为空。

【讨论】:

  • "如果您在调用 stmt.getString(6) 后调用 con.commit(),我希望您的 out 参数为空。" - 确定吗?
  • 既然你提到了它,可能不会 - 即使它没有提交事务,proc 也可以返回一个值。
【解决方案2】:

主要区别在于您持有交易的时间超过了必要的时间。您应该始终尝试尽可能快地提交,以尽量减少阻塞其他事务的可能性。特别是如果您正在执行诸如传输 BLOB 或大型文本字段之类的操作,这可能会占用大量事务日志空间(并且需要更多时间通过网络传输)。

【讨论】:

    【解决方案3】:

    区别在于异常处理。如果 getString 抛出异常,那么下面的提交将不会执行。后果取决于当前交易是否有任何变化**。如果您要跟踪两个版本的代码(没有抛出异常)然后比较两个跟踪文件,您将无法判断哪个版本的代码创建了每个跟踪,除非您留下某种标记(或保留每个用户进程的 spid)。

    您必须问自己一个问题:即使抛出异常,我也想提交吗?然后你就会知道如何编写代码了。

    ** 你的连接总是有一个事务打开。有些交易有变化,有些则没有。

    【讨论】:

      【解决方案4】:

      在我看来,如果 out 参数是简单类型,则在更大程度上是样式问题。但是,out 参数可以是例如光标。在自动提交的情况下,只有当游标类型输出参数或存储过程返回的所有结果集都关闭时,才会发生提交操作。如果在完全获取游标之前发出提交,则数据一致性是有问题的。为了避免这种歧义,我建议在读取所有输出参数后提交/回滚事务。

      【讨论】:

        【解决方案5】:

        只需将以上答案总结为一个答案即可快速总结:

        1- 如果提交,在读取所有输出参数之前,数据一致性是有问题的。所以这里方法2是不可取的。

        2-假设读取输出参数时发生异常,则不会提交事务。另一方面,如果我们希望事务在不关心输出参数的情况下被提交,我们可以在读取它们之前提交。

        3- 在方法 2 中,我们阻塞事务的时间更长。在上面的示例代码中,这没什么大不了的,但它可能是我们在提交之前做了很多事情的问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-01-02
          • 2012-02-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-16
          • 2020-02-25
          相关资源
          最近更新 更多