如何解决“存储过程'MySP1'可能只在非链接事务模式下运行”错误?

时间:2012-06-09 20:40:26

标签: java jdbc transactions sybase jtds

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

  • 使用net.sourceforge.jtds.jdbc.Driver
  • 打开Sybase连接
  • 调用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)的网址字符串。

    这也没有效果

  3. SET CHAINED OFF之后调用setAutoCommit() SQL:

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

    这没有效果。

  4. 调查了setAutoCommit()的工作原理

    这让我相信可能会有bug in the driver。但是,#1-#3应该解决这个问题

  5. 名为setAutoCommit(true)而不是setAutoCommit(false)

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

2 个答案:

答案 0 :(得分:1)

我的理解是jdbc的“Autocommit”与Sybase链接模式是一样的。

Autocommit true表示在每个语句之后提交 - 这是未链接的:事务不在一个“链”中,可以作为一个提交并回滚。

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

答案 1 :(得分:0)

这些年来,以防万一有人看到这里。

我偶然发现了同一案子。 您与方法3非常接近。 但在这种情况下,jTDS不会启动tran(但是在Unchained模式下是必需的)。您可以通过执行手动操作

begin transaction

刚运行后

SET CHAINED OFF