【问题标题】:Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous countEXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配。以前的计数
【发布时间】:2012-02-18 14:36:51
【问题描述】:

我收到有关提交和回滚的异常,但不确定我的存储过程到底出了什么问题。我已经阅读了其他此类问题的答案,但无法找到提交计数到底在哪里弄乱了。

所以,这是我使用的存储过程:

-- this is a procedure used for the purge utility. This procedure uses the parameters of a date and lets user select
-- if the leads that should be purge must be closed either before, on or since that date.
-- operator: 0-->less 1-->equal 2-->greater
-- @closed: closing date
-- leadscount: returns the count of leads deleted

IF OBJECT_ID ('LEAD_PURGE', 'P') IS NOT NULL
   DROP PROCEDURE LEAD_PURGE
go

CREATE PROCEDURE LEAD_PURGE
@purgextns INT,
@leadscount INT OUTPUT
AS
BEGIN
BEGIN TRANSACTION
CREATE TABLE #ASSIGNMENTS_DELETED
(
    ID NUMERIC(19, 0)
    PRIMARY KEY (ID)
)

CREATE TABLE #MAPRESULTS_DELETED
(
    ID NUMERIC(19, 0)
    PRIMARY KEY (ID)
)

CREATE TABLE #COMMAND_DELETED
(
    ID NUMERIC(19, 0)
    PRIMARY KEY (ID)
)

CREATE TABLE #PROGRESS_STATUS_DELETED
(
    ID NUMERIC(19, 0)
    PRIMARY KEY (ID)
)

CREATE TABLE #DETAILS_DELETED
(
    ID NUMERIC(19, 0)
    PRIMARY KEY (ID)
)

CREATE TABLE #NEEDS_DELETED
(
    ID NUMERIC(19, 0)
    PRIMARY KEY (ID)
)

insert into #ASSIGNMENTS_DELETED
select SEQID FROM ASSIGNMENT WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD);

SELECT @leadscount = (SELECT COUNT(*) FROM PURGE_LEAD);

INSERT INTO #MAPRESULTS_DELETED
SELECT ID FROM MAPRESULT WHERE ASSIGNMENTSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED)

INSERT INTO #COMMAND_DELETED
SELECT ID FROM EXECUTERULECOMMAND WHERE MAPRESULTID IN (SELECT ID FROM #MAPRESULTS_DELETED)

INSERT INTO #PROGRESS_STATUS_DELETED
SELECT PROGRESS_STATUS_ID FROM COMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED)

INSERT INTO #DETAILS_DELETED
SELECT DETAILID FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD)

INSERT INTO #NEEDS_DELETED
SELECT NEEDSID FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD)



DELETE FROM PROGRESS_STATUS WHERE ID IN (SELECT ID FROM #PROGRESS_STATUS_DELETED)

DELETE FROM EXECUTERULECOMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED)

DELETE FROM COMMAND WHERE ID IN (SELECT ID FROM #COMMAND_DELETED)

DELETE FROM SIMPLECONDITIONAL WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED)

DELETE FROM MAPPREDICATE WHERE ROWBP IN (SELECT ID FROM MAPROW WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED))

DELETE FROM MAPROW WHERE RESULT IN (SELECT ID FROM #MAPRESULTS_DELETED)

DELETE FROM MAPRESULT WHERE ID IN (SELECT ID FROM #MAPRESULTS_DELETED)

DELETE FROM ASSIGNMENTATTACHMENTS WHERE ASSIGNMENTSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED)

DELETE FROM LEADOBSERVER WHERE ASSIGNSEQ IN (SELECT ID FROM #ASSIGNMENTS_DELETED)

DELETE FROM MAPDESTINATIONS WHERE SUGGESTEDASSIGNID IN 
    (SELECT ID FROM SUGGESTEDASSIGNMENT WHERE ASSIGNMENT_SEQID IN (SELECT ID FROM #ASSIGNMENTS_DELETED))

DELETE FROM SUGGESTEDASSIGNMENT WHERE ASSIGNMENT_SEQID IN (SELECT ID FROM #ASSIGNMENTS_DELETED)

DELETE FROM PRODUCTINTEREST WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD)



CREATE TABLE #SALE_DELETED_EX
(
    ID NUMERIC(19, 0)
    PRIMARY KEY (ID)
)
INSERT into #SALE_DELETED_EX SELECT SALEEXSEQ FROM SALE WHERE SEQID IN (SELECT SALEID FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD))


DELETE FROM SALE WHERE SEQID IN (SELECT SALEID FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD))


DELETE FROM SALEEXTENSIONS WHERE 
    SEQID IN (SELECT ID FROM #SALE_DELETED_EX)

DELETE FROM LEADSALES WHERE LEADID IN (SELECT ID FROM PURGE_LEAD)


DELETE FROM NOTES WHERE OBJECTID IN (SELECT ID FROM #NEEDS_DELETED) OR OBJECTID IN (SELECT ID FROM #DETAILS_DELETED)

DELETE FROM HISTORYRECORD WHERE OBJECTID IN (SELECT ID FROM #DETAILS_DELETED)

DELETE FROM DETAIL WHERE SEQID IN (SELECT ID FROM #NEEDS_DELETED UNION SELECT ID FROM #DETAILS_DELETED)

DELETE FROM MESSAGES WHERE PROVIDERID IN (SELECT ID FROM PURGE_LEAD)

DELETE FROM ASSIGNMENT WHERE LEADSEQ IN (SELECT ID FROM PURGE_LEAD)

DELETE FROM LEAD WHERE SEQID IN (SELECT ID FROM PURGE_LEAD)

CREATE TABLE #PURGE_LEAD_E
(
    ID NUMERIC(19, 0)
    PRIMARY KEY (ID)
)

INSERT into #PURGE_LEAD_E Select SEQID FROM LEADEXTENSIONS WHERE 
    SEQID NOT IN (SELECT LEADEXSEQ FROM LEAD)

if @purgextns = 1 begin
    DELETE FROM LEADEXTENSIONS WHERE 
        SEQID  IN (SELECT ID FROM PURGE_LEAD_E)
end


DELETE FROM PURGE_LEAD;

DROP TABLE #ASSIGNMENTS_DELETED

DROP TABLE #MAPRESULTS_DELETED

DROP TABLE #COMMAND_DELETED

DROP TABLE #PROGRESS_STATUS_DELETED

DROP TABLE #DETAILS_DELETED

DROP TABLE #NEEDS_DELETED

DROP TABLE #PURGE_LEAD_E

DROP TABLE #SALE_DELETED_EX

COMMIT
END
go

现在我在下面的代码中调用这个过程:

    try {
        c = new ConnectionHelper().getConnection();
        String sql = "";
        if (shouldPurgeExtns) {
            progressModel.makeProgress("progress.deleting.dependents");
            purgeMultiselect(c, LEAD, isMSSQL);
        }
        sql = "{CALL " + TOPLinkManager.getSchemaPrefix()
                + "LEAD_PURGE (?,?)}";
        cs = c.prepareCall(sql);
        cs.setInt(1, shouldPurgeExtns ? 0 : 1);
        cs.registerOutParameter(2, java.sql.Types.INTEGER);
        cs.executeUpdate();
        int rowcount = cs.getInt(2);
        cs.close();
        progressModel.makeProgress("progress.recording.history");
        recordHistory(c, isMSSQL, LEAD, DateTypeDecorator.CLOSED, date,
                rowcount);
        done(progressModel);
        c.close();
        return true;
    } catch (Exception e) {
        Logs.main.error("Error Purging Leads", e);
        throw new Exception(e.getMessage());
    }

我在上面写着int rowcount = cs.getInt(2);

例外是:

com.microsoft.sqlserver.jdbc.SQLServerException: Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1454)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.processResults(SQLServerStatement.java:1083)
    at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getOutParameter(SQLServerCallableStatement.java:112)
    at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getterGetParam(SQLServerCallableStatement.java:387)

请帮帮我。 在 com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getValue(SQLServerCallableStatement.java:393) 在 com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.getInt(SQLServerCallableStatement.java:437) 在 marketsoft.tools.purge.PurgeUtils.PurgeLeads(PurgeUtils.java:283)

编辑:

因为我自己已经回答了这个问题......我现在想稍微改变一下这个问题。

为什么execute方法没有抛出异常???

【问题讨论】:

    标签: java sql-server database stored-procedures jdbc


    【解决方案1】:

    这通常发生在事务启动并且未提交或未回滚时。

    如果错误出现在您的存储过程中,这可以锁定数据库表,因为在没有异常处理的情况下由于一些运行时错误导致事务未完成 您可以使用如下所示的异常处理。 SET XACT_ABORT

    SET XACT_ABORT ON
    SET NoCount ON
    Begin Try 
         BEGIN TRANSACTION 
            //Insert ,update queries    
         COMMIT
    End Try 
    Begin Catch 
         ROLLBACK
    End Catch
    

    【讨论】:

      【解决方案2】:

      对不起各位!感谢您的所有努力,最后,这是我在存储过程中的一个非常小的错误:

      看线:

      if @purgextns = 1 begin
          DELETE FROM LEADEXTENSIONS WHERE 
              SEQID  IN (SELECT ID FROM PURGE_LEAD_E)
      end
      

      应该是#PURGE_LEAD_E

      您的所有回答帮助我对商店流程开发有了不同的看法。非常感谢!

      【讨论】:

      • 我仍在寻找为什么执行方法没有抛出错误的答案?
      • 是的!这就是我所说的观点:)
      • 程序是如何在这种语法下编译的
      【解决方案3】:

      @leadscount 变量究竟如何包含已删除的潜在客户数?

      这是我唯一看到它被使用的地方:

      SELECT @leadscount = (SELECT COUNT(*) FROM PURGE_LEAD);

      无论如何,要测试一下,为什么不在事务的上下文之外运行上面的代码呢?

      如果您确实需要将它放在事务中,请尝试将值加载到表变量中(创建一个只有一列的表)。由于他们不参与交易,您可以测试交易是否是您真正的问题。

      【讨论】:

      • 表 purge_lead 包含要删除的潜在客户 ID,这就是已删除潜在客户的计数
      • 是的!我稍后也会更改表格的内容
      【解决方案4】:

      你的 COMMIT 没有被命中,可能是因为一个错误。事务不会自动回滚

      最好的方法(和最佳实践)是添加一些 SQL 错误处理

      CREATE PROCEDURE LEAD_PURGE
        @purgextns INT,
        @leadscount INT OUTPUT
      AS
      SET NOCOUNT, XACT_ABORT ON;
      
      BEGIN TRY
        BEGIN TRANSACTION
      
        CREATE TABLE #ASSIGNMENTS_DELETED
        (
            ID NUMERIC(19, 0)
            PRIMARY KEY (ID)
        )
      
        ...
        DROP TABLE #SALE_DELETED_EX
      
        COMMIT TRANSACTION
      END TRY
      BEGIN CATCH
        IF XACT_STATE() <> 0 
            ROLLBACK TRANSACTION
        RAISERROR ('it broke', 16, 1)
      END CATCH
      go
      

      有关这里发生的事情的更多详细信息,请在此处查看我的回答 Nested stored procedures containing TRY CATCH ROLLBACK pattern?

      注意:当存储过程退出时,您不需要删除临时表,因为它们超出范围

      【讨论】:

      • 如果在执行过程中出现错误,为什么没有在execute方法上抛出?此外,我只使用一个存储过程。
      【解决方案5】:

      尝试在程序开头添加

      SET XACT_ABORT ON
      

      或者

      包裹你的陈述
      begin try 
        BEGIN TRANSACTION 
       Your TSQL code
      
        COMMIT
      end try 
      begin catch 
        ROLLBACK
        RAISERROR('Gotcha!', 16, 1)
      end catch
      

      要检查打开了多少未提交的BEGIN TRAN,请测试@@TRANCOUNT 系统变量

      【讨论】:

        猜你喜欢
        • 2015-06-23
        • 2016-06-21
        • 1970-01-01
        • 2014-03-22
        • 2014-10-25
        • 2016-07-21
        • 2018-03-11
        • 2015-12-21
        • 2021-05-23
        相关资源
        最近更新 更多