【问题标题】:SQL Server SET XACT_ABORT ON and JAVASQL Server SET XACT_ABORT ON 和 JAVA
【发布时间】:2017-05-01 14:03:09
【问题描述】:

我有一个按预期工作的存储过程。片段如下所示:

BEGIN
SET XACT_ABORT ON;
BEGIN TRANSACTION;  

INSERT Table1...;
INSERT Table2...;

COMMIT TRANSACTION; 
END

如果 Table2 发生错误,Table1 的插入会回滚。问题在于对存储过程的 Java 调用。如果 XACT_ABORT 开启,下面的代码不会抛出异常;

    psmt = conn.prepareStatement(query);
    psmt.setInt(1, id);
    psmt.execute();
    psmt.close();

我看到当我在 SQL Server Management Studio 中执行存储过程时,似乎返回了两条消息。一种成功,一种错误:虽然插入被回滚。

(1 row(s) affected)
Msg 515, Level 16, State 2...

在 Java 调用中需要什么来识别异常/错误? ...阅读所有消息?

【问题讨论】:

  • 对于其他搜索此内容的人。正如 Andomar 所说,并非所有客户端库都正确编写。请参阅以下内容:link

标签: java sql-server exception transactions


【解决方案1】:

尝试添加:

set nocount on;

在程序的顶部?

【讨论】:

  • 看起来成功了!但是我对 sql server/Java 的这种行为感到不舒服。任何指向外部信息或基本摘要的链接表示赞赏。
  • @paulj 请看我的回答。
  • 以前的 Perl 客户端也需要此功能。并非所有客户端库都考虑到多个结果集。
【解决方案2】:

在不远的过去,我一直在与XACT_ABORT 斗争,而你的问题让我踏上了记忆之路。我的问题与您的问题相似,似乎我的修复也适用于您的情况。
XACT_ABORT 将回滚所有事务,使您处于执行代码之前的状态.这意味着麻烦查询的所有记录,包括错误消息都将随风而去;然而,有一个地方可以从这个回滚中“安全”,那就是一个变量。您可以利用它为您工作,我将在下面向您展示。

这是我使用的代码结构:

BEGIN
    SET XACT_ABORT ON;
    BEGIN TRANSACTION;  
    DECLARE @MSG VARCHAR(MAX);

    BEGIN TRY
        INSERT Table1...;
    END TRY
    BEGIN CATCH
        SET @MSG = 'Table1: ' + ERROR_MESSAGE();
        GOTO failure; /* SEGMENT BELOW WHICH WOULD TAKE CARE OF YOUR ERROR MESSAGES*/
    END CATCH
    /* REPEAT ABOVE SEGMENT FOR ALL INSERTS*/

    GOTO SUCCESS; /* THIS IS HERE SO THAT YOU CAN SKIP THE FAILURE SEGMENT IN THE EVENT THAT ALL WENT WELL UP UNTIL HERE*/

    FAILURE:
        ROLLBACK; 
        RETURN @MSG;

    SUCCESS:
        COMMIT TRANSACTION; 
END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    • 2015-12-19
    • 2015-03-22
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多