Нужна помощь в управлении соединениями MySql - PullRequest
0 голосов
/ 13 мая 2010

У меня проблемы с поиском четкого объяснения пула соединений. Я создаю приложение с использованием коннектора .NET, который я скачал с mysql.com. Приложению требуется только одно соединение с БД, но оно будет работать одновременно примерно на 6 машинах в моей сети. Обычно я создаю соединение при запуске и просто оставляю его. Но я вижу много сообщений от людей, которые говорят, что это плохая практика. Также я обеспокоен тайм-аутами. Мое приложение будет работать 24 часа в сутки, 7 дней в неделю и без активности базы данных.

Я склоняюсь к следующему:

using (MySqlConnection conn = new MySqlConnection(connStr))
{
    conn.Open();
    // use connection
}

Но я не уверен, что понимаю, что происходит в фоновом режиме. Это на самом деле закрывает соединение и позволяет gc уничтожить объект, или есть встроенное поведение пула, которое сохраняет объект и повторно доставляет его при следующем попытке его создать?

Я, конечно, не хочу, чтобы приложение повторно аутентифицировалось по сети при каждом обращении к базе данных.

Может кто-нибудь предложить мне какой-нибудь совет?

Ответы [ 3 ]

0 голосов
/ 13 мая 2010

Согласно этому сообщению соединения сохраняются и объединяются по умолчанию в течение 60 секунд перед закрытием.

0 голосов
/ 13 мая 2010

Отключенная модель является наиболее используемой во всем мире, хотя она не злоупотребляет аутентификацией снова и снова.

Режим отключения

Вот несколько причин, по которым вы хотите работать в большинстве случаев без связи:

  1. Количество CLA (клиентских лицензионных соглашений), купленных для вашего сервера базы данных (ну, в действительности, здесь не применимо, поскольку это MySQL);
  2. Если одновременно подключено слишком много людей, это замедляет работу DBE (компонента Database Engine);
  3. Если открытые соединения остаются, сеть занята, а слишком загруженная сеть с большей вероятностью выйдет из строя;
  4. Пока пользователь редактирует, скажем, данные клиента, ему не нужно сохранять соединение с сервером базы данных и, возможно, блокировать строку или таблицу данных, что может привести к большим проблемам одновременной блокировки.

Этот код:

using(MySqlConnection conn = new MySqlConnection(connStr)) {
    if (conn.State == ConnectionState.Closed)
        try {
            conn.Open();
        } catch (MySqlException ex) {
            // Exception handling here...
        }
    // Use of connection here...
}

Ключевое слово using используется для автоматического удаления объектов, созданных в нем, как указано в статье:

Определяет область, за пределами которой объект или объекты будут расположены.

Таким образом, вы гарантируете, что если соединение больше не требуется, вы избавляетесь от него. Так что да, новая аутентификация потребуется после повторного создания этого подключения, поскольку оно больше не существует. В течение короткого времени здесь проводится небольшой опрос, но вам не о чем беспокоиться.

Режим соединения

Чтобы обеспечить использование только одного такого соединения в вашем приложении, вы должны использовать его как singleton . Однако, как только ваша строка подключения изменится, однажды вам нужно будет убедиться, что все приложение закрывается и снова открывается, так что это соединение получает обновленную строку соединения. Это нежизнеспособно, но я не знаю вашего контекста.

Использование прикладного блока доступа к данным корпоративной библиотеки

Для обеспечения управляемости пула подключений вы можете использовать Enterprise Library Блок приложения доступа к данным .

DAAB - это простой в использовании, полностью настраиваемый уровень доступа к данным, разработанный инженерами Microsoft и другими участвующими компаниями. Тогда управление пулом соединений может быть простым как 1-2-3!

Я думаю, вы могли бы многого добиться, используя DAAB, который полностью настраивается в XML-файле и требует очень низких затрат на обслуживание.

РЕДАКТИРОВАТЬ Если бы я мог продвинуться немного дальше, я бы, возможно, подумал бы об использовании шаблона проектирования Фасад с фабриками.

Эффективное использование шаблона проектирования фасадов и фабрик

Обладая «умным» фасадом, именно он обеспечивает вам необходимую связь. Таким образом, вот простой пример (при условии, что у вас есть настройка проекта с именем «DefaultConnectionString»):

public static class ApplicationFacade {
    private static readonly ApplicationFactory _applicationFactory = new ApplicationFactory();

    public static DefaultConnectionString {
        get {
            return Properties.Settings.Default.DefaultConnectionString;
        }
    }

    public static IList<ICustomer> GetCustomers() {
        using(var connection = OpenConnection())
           _applicationFactory.GetCustomers(connection);
    }

    public MySqlConnection OpenConnection() {
        var newConnection = new MySqlConnection(DefaultConnectionString);
        try {
            newConnection.Open();
        } catch (Exception ex) {
            // Exception handling...
        }
        return newConnection;
    }
}

internal sealed class ApplicationFactory {
    internal ApplicationFactory() {
    }

    internal IList<ICustomer> GetCustomers(MySqlConnection connection) {
        if (connection.State != ConnectionState.Open)
            throw new InvalidOperationException()

        IList<ICustomer> customers = new List<ICustomer>();

        var command = new MySqlCommand(connection, @"select * from Customers");
        // Place code to get customers here...

        return customers;
    }
}

// So you'll be able to use share the same connection throught your factory whenever needed, preventing the overkill of authentication over and over again. Here's how this would be used:

public partial class MainForm : Form {
    private void PopulateGrid() {
        dataGridView1.DataSource = ApplicationFacade.GetCustomers();
        // And you never care about the connection! All you want is the list of customers, that's all!
    }
}

Это шаблон, который я часто использую в своих проектах разработки. Это позволяет использовать единую точку входа в мои библиотеки классов, и они очень просты в использовании.

Ну, возможно, это больше, чем вы просили, но я надеюсь, что это поможет.

0 голосов
/ 13 мая 2010

Обычно провайдеры .net используют пулы соединений в этом сценарии.

Соединение должно просто вернуться в пул по окончании использования.

Я не заглядывал в ловушку с помощью профилировщика mysql, но у меня есть код, который зависит от него - у меня не было проблем с этим.

Обновление: Я только что посмотрел на вызовы, сделанные во время удаления, и он определенно выполняет пул соединений, то есть он заканчивает тем, что звонил:

internal void CloseFully()
{
    if (this.settings.Pooling && this.driver.IsOpen)
    {
        if ((this.driver.ServerStatus & ServerStatusFlags.InTransaction) != 0)
        {
            new MySqlTransaction(this, IsolationLevel.Unspecified).Rollback();
        }
        MySqlPoolManager.ReleaseConnection(this.driver);
    }
    else
    {
        this.driver.Close();
    }
    this.driver = null;
}

Обновление 2 / ответ на комментарий: Экземпляр MySqlConnection является другим, так как оператор using просто имеет дело с удалением (освобождением ресурсов). Из-за этого вам не нужно проверять, закрыто ли оно. MySqlConnection внутренне использует другие классы / экземпляры, то есть, если он захватывает соответствующий экземпляр. Это прозрачно для вашего кода, поэтому вы используете его так же, как если бы это было новое + другое соединение / как в коде, который вы опубликовали.

Как вы сказали, чтобы иметь возможность повторно использовать соединение более низкого уровня (называемое драйвером в коде соединителя mysql), каждый пул определяется строкой соединения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...