1

我正在尝试使用实体框架运行以下事务。在事务范围内,我从数据库调用存储过程。

 using (mother_Entities entitiesContext = context.Value)
 {
    using (var transactionScope = new TransactionScope())
    {   
        // a lot of create, insert, update operations goes here
        ...
        entitiesContext.SaveChanges();

        //Execute stored procedure:
        var paramMessage = new ObjectParameter("MESSAGE", "");
        var paramMotherid = new ObjectParameter("MOTHERID", motherProductId);
        var paramTochteridlist = new ObjectParameter("TOCHTER_ID_LIST", string.Join(";", motherIds));
        var paramError = new ObjectParameter("ERROR", typeof(int));
        var paramErrorText = new ObjectParameter("ERR_TEXT", typeof(string));

        entitiesContext.ExecuteFunction("SP_DOCUWARE_UPDATE", paramMessage, paramMotherid,
                                            paramTochteridlist, paramError, paramErrorText);

        ...
        transactionScope.Complete();
     }
 }

在线entitiesContext.ExecuteFunction()我得到异常Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0

我的存储过程不使用任何事务,也不调用任何其他函数或过程。所以我不明白为什么我不能在事务中执行存储过程。

更新:

哦,我在存储过程中找到了这个:

...
    IF @COMMIT = 1
    BEGIN
        IF @CANCEL = 1 
            ROLLBACK
        ELSE
            COMMIT
    END
    ELSE IF @CHECK = 1
        ROLLBACK
    END
...

可能是在提交异常被抛出之后。但是如何避免这个错误呢?

4

2 回答 2

3

我解决了我的问题。

在存储过程中有一个ROLLBACKCOMMIT关键字。但是BEGIN TRANSACTION程序中没有任何地方。从一开始,我就觉得这很奇怪。

如您所知,COMMIT递减@@TRANCOUNT1。或者更准确地说:

如果@@TRANCOUNT 为1,COMMIT TRANSACTION 使自事务开始以来执行的所有数据修改成为数据库的永久部分,释放事务持有的资源,并将@@TRANCOUNT 递减为0。如果@@TRANCOUNT 大于1,COMMIT TRANSACTION 仅将 @@TRANCOUNT 减 1,并且事务保持活动状态。

在我的例子中,我在代码中开始了一个事务。并且COMMIT在该过程中尝试提交我的事务并递减@@TRANCOUNT,但尚未完成。

所以我添加BEGIN TRANSACTION到存储过程中,它工作正常。

于 2013-10-09T07:33:34.393 回答
0

在提交内部事务(完成)之前,您不能提交外部事务(SaveChanges)。我怀疑对内部事务的调用SaveChanges也会提交内部事务。(未经审核的。)

于 2013-10-08T14:26:11.623 回答