我有一张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 Profiler 中看到以下查询执行,但没有关于回滚:
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上的另一个答案让我相信我做的一切都是正确的:如何在实体框架中回滚事务,所以......
我在这里想念什么?
到目前为止,我已经尝试围绕上下文的创建和 SaveChanges() 的每个重载来包装 TransactionScope using 语句。没有任何改变。
蒂亚!