使用Entity Framework在事务内部调用存储过程

时间:2013-10-08 13:06:13

标签: c# entity-framework stored-procedures transactionscope

我正在尝试使用Entity Framework运行以下事务。在事务范围内,我从DB调用存储过程。

 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

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

更新:

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

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

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

2 个答案:

答案 0 :(得分:3)

我解决了我的问题。

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

如您所知COMMIT@@TRANCOUNT递减1.或者更确切地说:

  

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

在我的情况下,我在代码中开始一个事务。并且过程中的COMMIT正在尝试提交我的事务并递减@@TRANCOUNT,但它尚未完成。

所以我将BEGIN TRANSACTION添加到存储过程中,它运行正常。

答案 1 :(得分:0)

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