【问题标题】:Sporadic "Multiple simultaneous connections are not currently supported"零星的“当前不支持多个同时连接”
【发布时间】:2013-04-23 14:14:55
【问题描述】:

我有一个使用 Entity Framework 和 MySQL 数据库的 ASP.NET Web 应用程序。我正在使用动态表做一些工作,因此不得不编写原始 SQL。我需要添加一些东西来使这个代码线程安全吗?我的系统的每个用户都可以并且将非常频繁地调用此代码。它总是针对 INFORMATION_SCHEMA 的调用错误。

这是我在尝试调用 AddMessageAction 时经常收到的错误(但不是每次):

UserActionModel:CheckTableExists ex: The underlying provider failed on Open..
4/23/2013 9:00:24 AM: UserActionModel:CheckTableExists inner ex: System.NotSupportedException: Multiple simultaneous connections or connections with different connection strings inside the same transaction are not currently supported.
   at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)
   at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex)
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure).

还有代码:

public static class UserActionModel
{

private const string databaseName = "chat";

public static string CheckTableExists(long _userId)
{
    string tableName = null;
    List<long> tableExists;

    try
    {
        string date = DateTime.Now.ToUniversalTime().Year.ToString() + DateTime.Now.ToUniversalTime().Month.ToString("D2") + DateTime.Now.ToUniversalTime().Day.ToString("D2");

        tableName = "user_actions_" + date + "_" + _userId;

        string sql = "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = 'archive'";

        using (var readContext = new ArchiveConnector())
        {
            tableExists = readContext.Database.SqlQuery<long>(sql).ToList();
            readContext.Database.Connection.Close();
        }

        if (tableExists.Any(tableExist => tableExist == 0))
        {
            sql = "CREATE TABLE IF NOT EXISTS `" + tableName + "` ("
                  + "`id` bigint(20) NOT NULL AUTO_INCREMENT, "
                  + "`user_id` bigint(20) NOT NULL, "
                  + "`user_device_id` bigint(20) NOT NULL, "
                  + "`coordinate_address_id` bigint(20) NOT NULL, "
                  + "`message_id` bigint(20) DEFAULT NULL, "
                  + "`created` datetime NOT NULL, "
                  + "PRIMARY KEY (`id`), "
                  + "KEY `user_id` (`user_id`), "
                  + "KEY `user_device_id` (`user_device_id`), "
                  + "KEY `coordinate_address_id` (`coordinate_address_id`), "
                  + "KEY `message_id` (`message_id`); "

            using (var writeContext = new ArchiveConnector())
            {
                writeContext.Database.ExecuteSqlCommand(sql);
                writeContext.SaveChanges();
                writeContext.Database.Connection.Close();

            }
        }
    }
    catch (Exception ex)
    {
        Logger.LogMessage("UserActionModel:CheckTableExists ex: " + ex.Message);

        if (ex.InnerException != null)
            Logger.LogMessage("UserActionModel:CheckTableExists inner ex: " + ex.InnerException);

        tableName = null;
    }

    return tableName;
}

public static void AddMessageAction(long _messageId, long _userId, long _userDeviceId, long _coordinateAddressId)
{
    try
    {
        string tableName = CheckTableExists(_userId);

        if (String.IsNullOrEmpty(tableName)) return;

        using (var dataContext = new ArchiveConnector())
        {
            string sql = "INSERT INTO " + tableName + " "
                + "(user_id, user_device_id, coordinate_address_id, message_id, created) "
                + "VALUES "
                + "(" + _userId + ", " + _userDeviceId + ", " + _coordinateAddressId + ", " + _messageId + ", NOW());";

            dataContext.Database.ExecuteSqlCommand(sql);
            dataContext.SaveChanges();
        }
    }
    catch (Exception ex)
    {
        Logger.LogMessage("UserActionModel:AddMessageAction (" + _messageId + ") ex: " + ex.Message);
    }
}
}    

从我的 web.config 连接字符串中删除 persist security info=True 没有任何区别(我了解到这是一个可能的解决方案)。

UDPATE:从连接器 6.6.4 更新到 6.6.5。不用找了。 UDPATE:从连接器 6.6.5 更新到 6.7.1 Alpha。没有变化。

【问题讨论】:

    标签: c# asp.net mysql entity-framework


    【解决方案1】:

    ArchiveConnectorDispose 方法未关闭其 MySQL 连接。当你:

    using (var writeContext = new ArchiveConnector())
    

    连接上:

    using (var readContext = new ArchiveConnector())
    

    仍处于打开状态,并且 MySQL 不支持同一事务上的多个连接。确保您的连接在 ArchiveConnector.Dispose() 上关闭。

    祝你好运。

    【讨论】:

    • 我以为using 块的末尾会自动处理所有 Dispose 调用??来自 MSDN:You create an instance in a using statement to ensure that Dispose is called on the object when the using statement is exited.
    【解决方案2】:

    我在另一个连接器上的 using 中调用了我的 AddMessageAction()。不要这样做。

    【讨论】:

      猜你喜欢
      • 2011-08-28
      • 2023-01-26
      • 1970-01-01
      • 1970-01-01
      • 2019-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-22
      相关资源
      最近更新 更多