问题
I've got a Publication table and a Receipt table. When I publish data out, I track it in the Publication table. When my test client receives that publication back from the broker, I track it in the Receipt table.
My Publication table has a denormalized ReceiptCount column on it for ease of reporting.
When my test consumer receives the Publication, the following code executes:
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;
}
The problem is if the insert on Receipt fails, the Publication.ReceiptCount is never rolled back. To just deleted the Receipt table to test it, and the ReceiptCount column continues to update successfully despite a System.Data.UpdateException being thrown. I see the following queries in SQL Profiler execute, but nothing about rollback:
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'
This other answer on SO leads me to believe I'm doing everything correctly: How to rollback a transaction in Entity Framework, so...
What am I missing here??
So far I've tried wrapping the TransactionScope using statement around the creation of the context and every overload of SaveChanges(). Nothing made a difference.
TIA!
回答1:
Pulling up my comments because they turned out to be answers:
Your observations mean that you are not generating transactions (you are using implicit transactions per-statement). Find out why the TScope did not take. Try putting it outside the new entities. Note, that if the TScope does not take no warning is generated. It just silently does nothing.
Does your conn str contain Enlist=false?
来源:https://stackoverflow.com/questions/15009764/entity-framework-transactionscope-not-rolling-back