是否可以将事务范围与在存储过程中提交事务相结合?

时间:2009-09-23 11:54:53

标签: c# sql-server entity-framework transactions transactionscope

我们有一个在事务范围内运行的测试。我们在最后处理事务范围以避免更改数据库。

在大多数情况下,这种方法很好。

但是,当我们使用Entity Framework执行包含在存储过程内提交的事务的存储过程时。我们收到以下错误:

“分布式事务已完成。请在新事务或NULL事务中登记此会话。\ r \ n”

是否可以将事务范围与在存储过程中提交事务相结合?

2 个答案:

答案 0 :(得分:6)

虽然您可能或可能无法解决此特定问题,但我建议完全避免它可能是更好的选择。正如您所见,根据事务来保证您的数据库处于特定状态并不总是有效。此外,因为您正在使用与DB的多个连接,所以您自动提升了对分布式事务执行的任何事务 - 可能是一种微妙的区别,但它会改变测试的性质。您最终可能会编写代码来克服分布式事务的特定限制,而这些限制本来是不需要的。

更好的策略是 - 无论如何,对于单元测试 - 模拟数据库依赖性,使用内存模拟或伪对象代替数据库。我已经为LINQ to SQL做了类似的事情(请参阅我关于这个问题的blog entry)对于集成测试,我认为你最好使用测试实例并编写设置代码,重新初始化数据库的状态以便知道每次测试之前的值比引入额外的事务来清理事物。这样,如果您的清理代码在测试中失败,它将不会影响正在运行的其他测试。

答案 1 :(得分:1)

我在SP中使用以下代码来处理事务当前可能有效或可能不有效的上下文: -

DECLARE @InTran int

Set @InTran = @@TRANCOUNT

IF @InTran = 0 BEGIN TRANSACTION

/* Stuff happens */

IF @InTran = 0 AND @@TRANCOUNT > 0 COMMIT TRANSACTION

我唯一不确定的是@@ TRANCOUNT是否反映了交易范围内的交易,但值得一试。