【发布时间】:2012-07-10 17:03:16
【问题描述】:
我们正在逐步用实体框架 (4.3.1) 替换遗留数据访问代码。在某些情况下,我们无法避免在一个工作单元中同时使用两种数据访问方式。理想情况下,这应该在一个事务中完成。但是,当一个工作单元完成并且 EF 管理自己的事务时,旧代码使用 SqlTransactions 调用 Commit()。
因此我们想到将“旧”和“新”代码包装在 TransactionScope 中。但是,即使 TransactionScope 未完成,周围的 TransactionScope 内的 Commit 也会始终执行。这段代码 sn-p 说明了我的问题:
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 来强制旧数据访问代码和上下文中的SaveChanges 在一个事务中执行。 或者有没有办法推翻 SqlTransaction.Commit 语句?
我知道这里有更多关于 TransactionScope 和 SqlTransaction 的帖子,但他们都(正确地)说在使用 TransactionScope 时不需要(也不推荐)使用 SqlTransaction。但是这里不使用 SqlTransaction 不是一个选项。我们有一个遗留框架,它提交自己的SqlTransactions,并且没有 api 来挂钩其事务机制。
【问题讨论】:
-
您至少可以访问连接吗?
-
@LadislavMrnka 不,除了配置文件中的连接字符串。
标签: c# entity-framework transactions transactionscope