当负载增加时 Dapper 崩溃

Dapper is crashing when load is increased

我在基于 .net 5.0 构建的支付处理应用程序中使用 dapper。在单元测试中,一切正常,但是当我使用 JMeter 加载 100 个用户时,在处理了一些事务之后,dapper 开始崩溃并出现以下错误:

Exception[System.InvalidOperationException: Connection must be open for this operation at Oracle.ManagedDataAccess.Client.OracleCommand.ValidateStatePriorToExecution() at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteNonQuery()
at Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, CommandDefinition& command, Action2 paramReader) in /_/Dapper/SqlMapper.cs:line 2822 at Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, CommandDefinition& command) in /_/Dapper/SqlMapper.cs:line 572 at Dapper.SqlMapper.Execute(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable1 commandTimeout, Nullable`1 commandType) in /_/Dapper/SqlMapper.cs:line 443

SP执行代码如下:

public static int ExecuteSP(string spName, object parameters)
{
    IDbConnection connection = ConnectionManager.GetConnection(_ConnectionString);

    int result = connection.Execute(spName, parameters, null, null, CommandType.StoredProcedure);

    ConnectionManager.CloseConnection();
    return result;
}

public static IDbConnection GetConnection(string connectionString)
{
     DefaultTypeMap.MatchNamesWithUnderscores = true;

     if (_oracleConnection == null)
     {
         _oracleConnection = new OracleConnection(GetConnectionString(connectionString));
     }

     if (_oracleConnection.State == ConnectionState.Closed)
     {
         _oracleConnection.Open();
     }
     return _oracleConnection;
}

我在配置或使用 Dapper 时是否遗漏了什么?

这里的错误是使用 static - 因此是共享 - 连接(即使没有显示,我们可以假设 _oracleConnectionstatic 因为它被访问来自 static 方法 GetConnection).

连接不是线程安全的,并且通过使其static,您的所有代码都共享一个连接。这往往会扩展到恰好一个用户,即一个并发请求 - 在此之上:几乎可以保证失败。

连接的范围应为逻辑代码段 - 可以是“单个方法”到“整个请求”之间的任何位置,但它们必须只能 被访问一次一个线程。您还应该确保连接在离开该范围时得到正确处理,以防止连接泄漏。

(顺便说一句:这个问题实际上与 Dapper 无关;任何类似的用法都会出现完全相同的问题 - 无论是 ADO.NET、Dapper、EF 还是其他任何东西)