0

私は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.UpdateExceptionSQL 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!

4

1 に答える 1

1

彼らが答えであることが判明したので私のコメントを引き出します:

あなたの観察は、あなたがトランザクションを生成していないことを意味します(あなたはステートメントごとに暗黙のトランザクションを使用しています)。TScopeが採用しなかった理由をご覧ください。新しいエンティティの外に配置してみてください。TScopeが取得しない場合、警告は生成されないことに注意してください。黙って何もしません。

conn strには含まれていますEnlist=falseか?

于 2013-02-21T22:24:52.863 に答える