实体框架TransactionScope没有回滚

时间:2013-02-21 18:34:21

标签: entity-framework transactionscope

我有一张Publication表和一张Receipt表。当我发布数据时,我会在Publication表中跟踪它。当我的测试客户端从代理接收到该发布时,我会在Receipt表中跟踪它。

我的Publication表格上有一个非规范化ReceiptCount列,以便于报告。

当我的测试用户收到发布时,执行以下代码:

try
{
    using (var context = new PublicationVerifierEntities())
    {
        using (var transaction = new TransactionScope())
        {
            if (request.PublicationGuid == Guid.Empty)
            {
                context.AddToUnknownPublications(new UnknownPublication
                {
                    DateReceived = request.DateReceived,
                    Publication = request.Publication,
                });
            }
            else
            {
                // look up the publication by Guid
                var publication = context.Publications.FirstOrDefault(m => m.PublicationGuid.Equals(request.PublicationGuid));

                if (publication == null)
                {
                    throw new Exception("UpdatePublicationReceipt, provided PublicationGuid not found in database.");
                }
                else
                {
                    context.AddToUnknownPublications(new UnknownPublication
                    {
                        DateReceived = request.DateReceived,
                        Publication = request.Publication,
                    });

                    context.AddToReceipts(new Receipt
                    {
                        DateReceived = request.DateReceived,
                        Publication = publication,
                    });

                    publication.ReceiptCount++;
                }
            }

            context.SaveChanges(System.Data.Objects.SaveOptions.None);
            transaction.Complete();
            context.AcceptAllChanges();
        }
    }
}
catch (Exception ex)
{
    _logger.Error("Unable to update publication record receipt.", ex);
    throw;
}

问题是如果Receipt上的插入失败,Publication.ReceiptCount永远不会回滚。要删除Receipt表以对其进行测试,ReceiptCount列会继续成功更新,尽管会抛出System.Data.UpdateException。我在SQL事件探查器中看到以下查询执行,但没有关于回滚的信息:

exec sp_executesql N'update [dbo].[Publication]
set [ReceiptCount] = @0
where ([PublicationId] = @1)
',N'@0 int,@1 int',@0=10,@1=3414639

exec sp_executesql N'insert [dbo].[Receipt]([PublicationId], [DateInserted], [DateReceived])
values (@0, null, @1)
select [ReceiptId]
from [dbo].[Receipt]
where @@ROWCOUNT > 0 and [ReceiptId] = scope_identity()',N'@0 int,@1 datetime',@0=3414639,@1='2013-02-21 18:12:47:513'

关于SO的另一个答案让我相信我正在做的一切正确:How to rollback a transaction in Entity Framework,所以......

我在这里缺少什么?

到目前为止,我已经尝试使用围绕创建上下文和SaveChanges()的每个重载的语句来包装TransactionScope。什么都没有区别。

TIA!

1 个答案:

答案 0 :(得分:1)

提出我的意见,因为结果证明是答案:

您的观察意味着您没有生成事务(您使用隐式事务per语句)。找出TScope没有采取的原因。尝试将其放在新实体之外。注意,如果TScope没有采取任何警告,则会生成。它只是默默无闻。

你的conn str包含Enlist=false吗?