私は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に関するこの他の回答は、私がすべてを正しく行っていると私に信じさせます。EntityFrameworkでトランザクションをロールバックする方法。
私はここで何が欠けていますか?
これまで、コンテキストの作成とSaveChanges()のすべてのオーバーロードについて、ステートメントを使用してTransactionScopeをラップしてみました。何も違いはありませんでした。
TIA!