忽略TransactionScope中的SqlTransaction.Commit

时间:2012-07-10 17:03:16

标签: c# entity-framework transactions transactionscope

我们正在逐步用实体框架(4.3.1)替换遗留数据访问代码。在某些情况下,我们无法避免在一个工作单元中使用两种数据访问方式。理想情况下,这应该在一个事务中完成。但是,当完成一个工作单元并且EF管理自己的事务时,旧代码使用调用SqlTransaction的{​​{1}}。

所以我们想到在TransactionScope中包装“旧”和“新”代码。但是,即使Commit()未完成,也始终会执行周围TransactionScope内的提交。此代码段说明了我的问题:

TransactionScope

如果未using (var conn = new SqlConnection("connection string")) { conn.Open(); using (var scope = new TransactionScope()) { using (var tr = conn.BeginTransaction()) { using (var cmd = conn.CreateCommand()) { cmd.Transaction = tr; cmd.CommandText = "some update statement"; cmd.ExecuteNonQuery(); } tr.Commit(); } // In reality the code above is part of a legacy DAL, immutable. // (can't insert SaveChanges before tr.Commit). context.SaveChanges(); if (<all ok>) // pseudo code for exception handling. scope.Complete(); } } 未命中,则仍会提交更新语句

看来,我不能使用scope.Complete()强制旧数据访问代码和上下文中的TransactionScope在一个事务中执行。 或者有没有办法推翻SqlTransaction.Commit语句?

我知道这里有关于TransactionScope和SqlTransaction的更多帖子,但他们都(正确地)说使用TransactionScope时不需要(也不推荐)使用SqlTransaction。但不使用SqlTransaction不是一个选项。我们有一个遗留框架,它提交自己的SaveChanges并且没有api可以挂钩它的事务机制。

1 个答案:

答案 0 :(得分:7)

  

当未触发scope.Complete()时,仍会提交更新语句。

哦不!没有使用TransacationScope 1

如果在之后(或中),则

仅在

Open 置于 TransactionScope 应该解决此问题(即使是手动事务?),因为Connection会[通常] ]在环境TS上下文中自动登记。

现有连接可以加入环境事务范围:connection.EnlistTransaction(Transaction.Current)

或者,可以从现有交易创建TS,例如, new TransactionScope(transaction),在这里可能有用,也可能没用。

创建一个手动交易,如果完全没问题,但TS(在找到问题之后!)使处理交易更简单,更容易..至少在大多数情况下:)

快乐的编码!


1 TS未用于“更新声明”。它仍然[可能]用于context.SaveChanges(),因为它会打开新的连接,然后自动登记。

我在上面提供了一些选项,虽然我不确定简单的“嵌套”事务。看到上下文中使用的(密封?)API可能会揭示关于限制/限制的更多见解。