1

私はこのようなテーブルを持っています

UserPageId (Primary Key) int
UserId (user Foreign Key) int
PageId (page Foreign Key) int

全体のシナリオは、ユーザーが 1 つのページを複数回追加するのを防ぐことです。各ユーザーによると、複数のユーザーで使用でき、同時ユーザーがいる可能性があります。

最初に分離レベルSerializableでこれを解決したいのですが、デッドロックで終わります

私の機能は次のとおりです。

public void Add(int PageId,int UserId)
{

        using (TransactionScope scope = newTransactionScope(TransactionScopeOption.RequiresNew,
            new TransactionOptions { IsolationLevel = IsolationLevel.Serializable }))
        {
            using (entities EFmodel = new entities())
            {
                EFmodel.Connection.Open();
                EFmodel._UserId = UserId;

                if (!Pages.Exists(EFmodel, PageId))
                    Pages.Add(EFmodel, PageId);
                else
                    ERModel.AddModelError("", "you have already added this page");
                EFmodel.SaveChanges();
            }
            scope.Complete();
        }
        return ERModel;
}

Pages.Exist:

public bool Exists(entities EFmodel, int PageId)
{
        int ctn = EFmodel.UserPages.Count(x => x.PageId == PageId && x.UserId == EFmodel._UserId);
        if(ctn!=0)
        return true;
        return false;
}

Pages.Add:

public static void Add(entities EFmodel,int PageId)
{
        UserPage userpage = new UserPage()
        {
            UserId = EFmodel._UserId,
            PageId = PageId,
            UserPageId = 0
        };
        EFmodel.UserPages.AddObject(userpage);
}
4

1 に答える 1

2

更新の異常を防止し、シリアル化の失敗を回避しながら、共有データの同時更新を許可する方法はありません。デッドロックは、シリアル化の失敗の 1 つのタイプです。秘訣は、一般化された方法でシリアライゼーションの失敗をキャッチし、影響を受けたトランザクションを再試行するレイヤーを介してデータベース要求をルーティングすることです。

于 2012-04-09T16:33:19.327 に答える