打开第二个 OdbcConnection 时断言失败

Assertion Failed when opening a second OdbcConnection

我写了一个 API 使用 .net Core 3.1

连接到 Sybase 后端

它需要在被调用时打开一个到 Sybase 数据库的 ODBC 连接。

如果我在 API 出现后调用它,它就可以正常工作。我什至可以连续调用它数百次

然而,当我等待 90 秒并使用相同的调用再次调用 API 时,我在 Microsoft C++ 运行时库 threads.c 中得到一个 Assert Failure 弹出窗口 window,看起来像这样:

*Application popup: Microsoft Visual C++ Runtime Library : Assertion failed!
Program: c:\windows\system32\inetsrv\w3wp.exe
File: .\threads.c
Line: 334
Expression: destructors_set[keynum] == 0
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts
(Press Retry to debug the application - JIT must be enabled)*

它一直发生在 connection.Open() 上;说明。

它在我调试时在服务器上或本地弹出,并在我调试时使服务器或 IISExpress 上的 IIS 工作线程崩溃。 API 在您中止时崩溃,然后在重新启动时它具有完全相同的行为。如果我在警报上单击忽略,它会正常完成。

我尝试 运行 DbConnect class 作为注入容器中的 Singleton、Scoped 甚至 Transient 对象。我什至尝试删除所有依赖项注入,以防它们导致问题。他们都这样做。我不知道该检查什么了。

public class DbConnect : IDbConnect
{
    private ILogger<DbConnect> _logger;

    public DbConnect(ILogger<DbConnect> logger)
    {
        _logger = logger;
    }
    public DataTable OdbcSelectQueryNew(string query)
    {
        DataTable dt = new DataTable();
        string connStr = "";//<--- removed for brevity and hard-coded for testing
        try
        {
            using (var connection = new OdbcConnection(connStr))
            {
                connection.Open();
                OdbcCommand command = new OdbcCommand(query);
                command.Connection = connection;
                OdbcDataAdapter adapter = new OdbcDataAdapter(command);
                adapter.Fill(dt);
            } 
            return dt;
        }
        catch (Exception e)
        {
            _logger.LogError("Log the error", e.ToString());
            throw;
        }
    }
}

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    
    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddSingleton<IComLog, ComLog>();
        services.AddHttpContextAccessor();
        services.AddSingleton<IDbConnect, DbConnect>();
    }
}

我找到了造成这种情况的根本原因。虽然没有说明,因为我从来没有想过它可能会导致问题,但当我使用 mitkerberos 作为身份验证客户端时,就会发生这种情况。

我的连接字符串如下所示:

Driver={Adaptive Server Enterprise};server=fakeservername;port=5050;Database=fakedbname;AuthenticationClient=mitkerberos;ServerPrincipal=fakeserverprincipal@fakedomain.COM

如果我恢复到具有 username/pwd 的 connectionString,如下所示:

Driver={Adaptive Server Enterprise};server=fakeservername;port=5050;UID=fakeuserid;PWD=fakepassword;Database=fakedatabase;PacketSize=4096;Persist Security Info=true;Max Pool Size=250; 一切都很好,错误从未发生,后续连接正常工作。

我不知道如何解决这个问题。也许是麻省理工学院的 Kerberos 客户端有缺陷?我不确定现在如何使用 kerberos 身份验证连接到远程数据库,但至少找到了断言失败的根本原因。

我通过完全摆脱 MIT-Kerberos 来实现这个功能。就是不稳定。

我现在正在使用 windows 内置的 kerberos 票证身份验证,它似乎很稳定,不会使我的应用程序池崩溃。

我的连接字符串现在看起来像这样: Driver={Adaptive Server Enterprise};server=fakeservername;port=5050;Database=fakedbname;AuthenticationClient=activedirectory;UserPrincipal=fakeuserprincipal@FAKEDOMAIN.COM;ServerPrincipal=fakeserverprincipal@FAKEDOMAIN.COM;PacketSize=4096;Max Pool尺寸=250;

其中 fakeuserprincipal 是我的应用程序池用于其身份的用户,fakeuserprincipal 是 kerberos spn 中定义的 Sybase 主机 ID。