4

我正在编写一个 Java 应用程序,它需要执行一些复杂的 SQL 并在其中任何一个失败时回滚所有这些:

  • 使用打开 Sybase 连接net.sourceforge.jtds.jdbc.Driver
  • 调用 setAutoCommit(false)
  • 做 SQL1
  • 调用存储过程“MySP1”
    • 存储过程 MySP1' 不在我的控制之下
    • 它有EXEC sp_procxmode 'dbo.MySP1','unchained'
  • 做 SQL2
  • 如果 SQL2 失败,则回滚所有内容(包括 SQL1),否则提交。

完成后,我从 MySP1 收到以下错误:

存储过程“MySP1”只能在非链式事务模式下运行。' SET CHAINED OFF' 命令将导致当前会话使用非链式事务模式。


我尝试了以下方法,但都没有帮助:

  1. 将“chained=false”添加到传递给getConnection()方法(advice source)的 Properties 对象。

    这没有效果,很可能是因为在我看来net.sourceforge.jtds.jdbc.Driver支持chained属性。

  2. 将“chained=false”添加到传递给getConnection()方法(advice source)的 URL 字符串。

    这也没有效果

  3. 之后调用SET CHAINED OFFSQL setAutoCommit()

      PreparedStatement st = conn.prepareStatement("SET CHAINED OFF");
      st.execute();
    

    这没有效果。

  4. 研究如何setAutoCommit()运作

    这使我相信驱动程序中可能存在错误。但是,如果是这种情况,#1-#3 应该已经解决了这个错误

  5. 调用setAutoCommit(true)而不是setAutoCommit(false).

    这修复了关于非链接模式的错误,但据我了解,这意味着我不能在最后回滚 100% 的 SQL,因为到那时第一个 SQL 语句已经被自动提交。

4

2 回答 2

1

我的理解是jdbc的“Autocommit”和Sybase链式模式是一回事。

自动提交 true 意味着在每条语句之后提交 - 这是未链接的:事务并非都在一个可以提交和回滚的“链”中。

所以你可能会被卡住。如果您无法更改该 SP,那么它将始终关闭链接模式。你得到一个合理的信息。它实际上是一条错误消息,还是只是您的jdbc代码没有处理它(即显示它或不显示它,但至少将其视为不是错误?)

于 2013-05-20T08:36:47.257 回答
0

以防万一这么多年后有人来看这里。

我偶然发现了同样的情况。您与方式 3 非常接近。但在这种情况下,jTDS 不会启动 tran(但在 Unchained 模式下是强制性的)。您可以通过执行手动执行

begin transaction

刚跑完

SET CHAINED OFF
于 2020-06-04T22:51:17.647 回答