C# 使用实体框架调用事务内部的存储过程
我正在尝试使用实体框架运行以下事务。在事务范围内,我从DB调用存储过程C# 使用实体框架调用事务内部的存储过程,c#,entity-framework,stored-procedures,transactionscope,C#,Entity Framework,Stored Procedures,Transactionscope,我正在尝试使用实体框架运行以下事务。在事务范围内,我从DB调用存储过程 using (mother_Entities entitiesContext = context.Value) { using (var transactionScope = new TransactionScope()) { // a lot of create, insert, update operations goes here ... ent
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()
I get exceptionTransaction count after EXECUTE指示BEGIN和COMMIT语句的数量不匹配。上一次计数=1,当前计数=0
我的存储过程不使用任何事务,也不调用任何其他函数或过程。所以我不明白为什么我不能在事务中执行strored过程
更新:
哦,我在存储过程中发现了这个:
...
IF @COMMIT = 1
BEGIN
IF @CANCEL = 1
ROLLBACK
ELSE
COMMIT
END
ELSE IF @CHECK = 1
ROLLBACK
END
...
可能是在引发提交异常之后。但是如何避免此错误?在提交内部事务(完成)之前,不能提交外部事务(保存更改)。我怀疑对
SaveChanges
的调用也会在内部提交内部事务。(未验证。)我解决了我的问题
在存储过程中有一个回滚
和提交
关键字。但是在过程中的任何地方都没有begintransaction
。从一开始,我就觉得很奇怪
正如您所知,COMMIT
将@@TRANCOUNT
递减1。或者更准确地说:
如果@TRANCOUNT为1,则提交事务将进行所有数据修改
自交易开始后执行,是交易的永久部分
数据库,释放事务所持有的资源,并递减
@@TRANCOUNT为0。如果@TRANCOUNT大于1,则提交事务
仅将@@TRANCOUNT递减1,事务将保持活动状态
在我的例子中,我在代码中开始一个事务。过程中的COMMIT
正在尝试提交我的事务并减少@@TRANCOUNT
,但尚未完成
因此,我在存储过程中添加了
begintransaction
,它运行良好。我认为这与TransactionScope无关,而是与存储过程有关。请在调用前检查存储过程是否正在使用您正在传递/设置的参数。您说“正在使用参数”是什么意思?我更新了我的问题。我的意思是,对于具有相同值的探查器跟踪,它是否能够在SQL server Management studio中运行异常…使用事务作用域时,SaveChanges不会提交任何更改。您必须使用transactionScope.Complete()来完成它;这是预期的行为。您在内部事务范围之外做什么?你真的需要它吗?我相信在隐式DbContext
事务范围内使用ExecuteFunction
将在同一事务内执行它,这看起来就像您想要的那样。您还应该考虑后端限制,例如SQL Server并不真正支持嵌套事务(它只是),这就解释了这种行为。因此,是的,删除显式事务范围是否有帮助?