ASP.NET Core中的MongoDB驱动程序死锁

时间:2018-07-15 20:31:31

标签: asp.net mongodb asp.net-core deadlock mongodb-.net-driver

我有带有两个控制器的简单asp.net WebApi项目。 第一个控制器使用 System.Linq ,并且在重负载下会出现死锁。其次使用 MongoDB.Driver.Linq 并运行良好。

我使用了ab -c 10 -n 200000 -p post -H'内容类型:application / json'-T'application / json''http://localhost:1989/api/SystemLinq/find'

为什么使用System.linq会出现死锁?

仅当读取数据后引发新的Exception时才发生死锁。我用IExceptionFilter捕获的异常。完整项目https://github.com/artyukh/AspNetMongoDeadlock

具有死锁的控制器

SELECT l1.username "User",
       l2.username "Following"
       FROM login l1
            INNER JOIN followers f
                       ON f.idsta = l1.id
            INNER JOIN login l2
                       ON l2.id = f.idfol
       WHERE l1.id = 3;

工作控制器

using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
using System.Linq;
using TestDeadlock.Core;

namespace TestDeadlock.Controllers
{
    [Route("api/[controller]")]
    public class SystemLinqController : Controller
    {
        private MongoContext _context;

        public SystemLinqController(MongoContext context)
        {
            _context = context;
        }

        [HttpPost]
        [Route("find")]
        public void Find([FromBody]AuthenticateInputDTO input)
        {
            var result = _context.UserSet.AsQueryable().Where(u => u.Email == input.Username).FirstOrDefault();
            if (result == null)
                throw new BusinessException("User not found");
        }
    }
}

ConfigureServices

using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using TestDeadlock.Core;

namespace TestDeadlock.Controllers
{
    [Route("api/[controller]")]
    public class MongoLinqController : Controller
    {
        private MongoContext _context;

        public MongoLinqController(MongoContext context)
        {
            _context = context;
        }

        [HttpPost]
        [Route("find")]
        public void Find([FromBody]AuthenticateInputDTO input)
        {
            var result = _context.UserSet.AsQueryable().Where(u => u.Email == input.Username).FirstOrDefault();
            if (result == null)
                throw new BusinessException("User not found");
        }
    }
}

GlobalExceptionFilter

public void ConfigureServices(IServiceCollection services)
        {
            var appSettings = Configuration.GetSection("AppSettings");

            // Add framework services.
            services.AddMvc(options =>
            {
                options.Filters.Add(new GlobalExceptionFilter());
            });

            services.AddMvc();

            services.Configure<MongoSettings>(options =>
            {
                options.ConnectionString
                    = Configuration.GetSection("MongoConnection:ConnectionString").Value;
                options.Database
                    = Configuration.GetSection("MongoConnection:Database").Value;
            });
            services.AddSingleton<MongoContext>();
        }

0 个答案:

没有答案