在事务范围内删除用户时超时

bjs*_*arf 2 c# asp.net-mvc entity-framework transactionscope asp.net-identity

  • 背景

我们正在尝试归档旧的用户数据,以使我们最常用的表更小。

  • 问题

    用于删除记录的普通 EF 代码适用于我们的自定义表。AspNetUsers 表是另一回事。看来这样做的方法是使用_userManager.Delete_userManager.DeleteAsync。这些工作无需尝试在一个事务中进行多个数据库调用。当我将其包装在 transactionScope 中时,它会超时。下面是一个例子:

    public bool DeleteByMultipleIds(List<string> idsToRemove)
    {
        try
        {
            using (var scope = new TransactionScope())
            {
                foreach (var id in idsToRemove)
                {
                    var user = _userManager.FindById(id);
                    //copy user data to archive table
                    _userManager.Delete(user);//causes timeout
                }
                scope.Complete();
            }
            return true;
        }
        catch (TransactionAbortedException e)
        {
            Logger.Publish(e);
            return false;
        }
        catch (Exception e)
        {
            Logger.Publish(e);
            return false;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

请注意,在代码运行时,我直接调用数据库,例如:

    DELETE
    FROM ASPNETUSERS
    WHERE Id = 'X'
Run Code Online (Sandbox Code Playgroud)

它也会超时。此 SQL 在执行 C# 代码之前起作用。因此,似乎超过 1 db 的命中似乎锁定了表。如何在一个事务中找到用户(db hit #1)并删除用户(db hit #2)?

Mer*_*nzo 5

对我来说,问题涉及DbContext在同一事务中使用多个单独的s。该BeginTransaction()方法不起作用。

在内部,UserManager.Delete()正在调用包装器中的async方法RunSync()。因此,将TransactionScopeAsyncFlowOption.Enabled参数用于我的TransactionScope工作:

using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    _myContext1.Delete(organisation);
    _myContext2.Delete(orders);
    _userManager.Delete(user);
    scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)