如何使用多个嵌套的事务范围?

时间:2009-06-09 16:15:22

标签: c# linq-to-sql transactions

我在linq2sql中做了一些需要在事务中运行的操作。但是,我在事务内部使用的一些方法也使用linq2sql并在自己的事务中运行(内部事务在存储过程中运行)。这给了我例外

[TransactionInDoubtException: The transaction is in doubt.]
   System.Transactions.TransactionStateInDoubt.EndCommit(InternalTransaction tx) +76
with the inner exception
[SqlException (0x80131904): There is already an open DataReader associated with this Command which must be closed first.]

如果我对SQL Server使用MultipleActiveResultSets,我会得到异常

[SqlException (0x80131904): The transaction operation cannot be performed because there are pending requests working on this transaction.]

有没有人有过以这种方式使用linq2sql和transactionscopes的经验?

4 个答案:

答案 0 :(得分:2)

这对我来说是一个“面子”的时刻,但考虑到我看到了这种确切的行为,并没有立即打击我,我想我会继续发布这个可能性:

当我为ReadUncommitted设置TransactionScope时,我看到了这种行为:

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, 
       new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted })

我的Linq to SQL正在调用存储过程来返回proc的结果。 face-pal是在proc本身内可以指定WITH(NOLOCK)SQL提示,因此不需要在ReadUncommitted事务范围中包装Linq to SQL查询。 (至少在我的情况下)

答案 1 :(得分:1)

我想,您正在尝试读取一些数据并在运行中进行修改(当读数仍在进行中时)。
在这种情况下,最简单的选择是首先读取所有数据(例如,使用IEnumerable<> .ToList()扩展方法),然后对数据执行所有操作。

答案 2 :(得分:0)

我知道我们在目前正在进行的项目中遇到过这个问题,我知道它与使用sproc时生成dbml文件的LinqToSql有关。我们必须手动完成它才能使它工作。 LinqToSql显然从sproc返回了ISingeResult,并产生了错误。

我不是纠正错误的人,但我知道这与此有关。

更多信息:http://www.west-wind.com/weblog/posts/246222.aspx

答案 3 :(得分:0)

我知道这是一个老线程,但它是谷歌对此错误的最高级别打击所以我认为值得添加我的答案。在我的情况下,我使用实体框架,所以甚至不确定它适用,但即便如此,一些使用EF的人可能会来这里。在我的情况下,这是因为我正在调用存储过程而不对返回的行做任何事情。因为EF没有读回行,所以这是“开放操作”。我的解决方案是简单地将First()添加到每个过程调用的结尾:

myentities.CallMyStoredProc(A, B, C).First();