Форум программистов, компьютерный форум, киберфорум
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
748 / 547 / 48
Регистрация: 17.06.2010
Сообщений: 1,039
Записей в блоге: 1
1

Многопоточная работа с MySql. Слишко много соединений

07.04.2014, 17:29. Показов 2988. Ответов 7
Метки нет (Все метки)

Добрый день!
В приложении, которое работает с базой данных MySql имеется функционал по считыванию данных из базы в отдельных потоках. Для mysql.Connection используется один экземпляр соединения. Создается оно один раз со строкой подключения из файла. Часть класса создания соединения с базой
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
        [ThreadStatic]
        private static MySqlConnection curconnection; // текущее подключение
        private static string conStr; 
 
        static MySqlWrapping()
        {
          
                curconnection = Create();
             
        }
 
 
        private static MySqlConnection Create()
        {
          
                    if (curconnection == null)
                    {                                          
                        ReinicialSettings(conStr);
                    }
               
            
            return curconnection;
        }
 
 // переинициализация строки подключения
        public static void ReinicialSettings(string conString)
        {
            conStr = conString;           
            curconnection = new MySqlConnection(conString);
        }
 
 /// <summary>
        /// Текущий экземпляр соединения к базе
        /// </summary>
        public static MySqlConnection CurConnection
        {
            get 
            {
                if (curconnection.State != System.Data.ConnectionState.Open)
                {
 
                    try
                    {
                        curconnection.Open();
                    }
                    catch (Exception)
                    {
 
 
                    }
                }
                return curconnection; 
            }
           
        }
По сути у меня всего один экземпляр соединения на все приложение. Но поскольку есть метка [ThreadStatic] то для каждого потока создается своя копия экземпляра соединения. Проблема в том, что на сервере таких соединений накапливается очень много. И в один прекрасный момент сервер свободные слоты для подключения заканчиваются. Во всех методах 100% все соединения всегда корректно закрываются. Я проверил. Как избежать этого копления экземпляров соединений? Заранее спасибо. Может кто подскажет оптимальную архитектуру даже?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.04.2014, 17:29
Ответы с готовыми решениями:

Тип соединение MYSQL. Превышено максимальное количество соединений
Для работы с БД использую MySQLConnector. Открывается постоянное соединение, которое мне не нужно....

Android 4.1 на HTC One S: используется слишко много памяти
Hi all. Проблема такова: занято слишком много оперативной памяти. Из 1 гигабайта уже при включении...

Excel 2002 выдает ошибку слишко много форматов при форматировании
У меня в Excel 2002 выдает ошибку слишко много форматов при форматировании . Правда файл большой...

Многопоточная запись в бд mysql
Добрый день. Написал скрипты на php которые считывают информацию с коммутаторов, делают некие...

7
1517 / 1081 / 152
Регистрация: 23.07.2010
Сообщений: 6,003
07.04.2014, 21:01 2
Singleton+ThreadStatic - может на 3х-звенку заменить стоит? Клиент дергает сервис, у сервиса - пул соединений?

Не по теме:


Топик интересный, мыслей полет - есть чего пообсуждать, не?;)

0
748 / 547 / 48
Регистрация: 17.06.2010
Сообщений: 1,039
Записей в блоге: 1
07.04.2014, 21:07  [ТС] 3
pincet, хорошо. возможно и стоит. но вот где гарантия что на mysql не будет висеть множество спящих соединений? и можете подробнее расписать, как вы бы сделали архитектуру приложения?
0
1517 / 1081 / 152
Регистрация: 23.07.2010
Сообщений: 6,003
07.04.2014, 21:51 4
к сожалению, с MySQL знаком слабо, гугл про спящие процессы в основном говорит про неверное закрытие соединений.
Теперь "архитектура"
Если критичен читатель - может, стоит "кластер" соорудить? На серверах(одном сервере с виртуалками) поднять n MySQL, выделить группы запросов (соответственно, физические таблицы размещать на своей ветке кластера+один сервер (если потребуется) для неизвестных на данный момент запросов). Сервис клиенту предоставляет возможность запросить операцию и сам принимает решение - в где брать данные. Вполне серверов с одинаковой структурой может быть больше одного.
Это раз.
Два - что делать с INSERT, UPDATE & DELETE. Та же служба вполне может справиться - вопрос в актуальности данных.
Как-то так. Но это - теория, куски реализовывал, вместе собрать - негде было. Посему - форумчане - давайте будем поделиться опытом
1
1055 / 862 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
08.04.2014, 10:38 5
gitarillo, на деле лучше не использовать поле-Connection
следует писать так
C#
1
2
3
4
using(SqlConnection  conn = new SqlConnection("Строка подключения"))
{
//тут используем подключение
}
таким образом соединение будет гарантировано закрыто(на самом деле отправлено в пул подключений). По умолчанию пул подключений удаляется только по завершению приложения (даже если нет ни одного объекта SqlConnection)
1
748 / 547 / 48
Регистрация: 17.06.2010
Сообщений: 1,039
Записей в блоге: 1
08.04.2014, 10:41  [ТС] 6
Learx, это конечно хорошо. правильно ли я понял что нужно при каждом запросе заново создавать соединение в блоке using? ведь операция создания соединения не маленькая и ресурсопожирающая
0
1055 / 862 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
08.04.2014, 10:44 7
Лучший ответ Сообщение было отмечено gitarillo как решение

Решение

если уж хотите вынести подключение отдельно, то тогда это должно выглядеть как-то так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
static sealed class ConnectionFactory
{
    private string connection = @"строка подключения";//еще лучше создать зашифрованный файл-конфигурацию и брать с него
    public static SqlConnection GetConnection()
    {
           return new SqlConnection(connection);
    }
}
//используем
using( SqlConnection conn = ConnectionFactory.GetConnection())
{
}
Добавлено через 1 минуту
gitarillo, еще раз повторюсь - ADO.NET реализован таким образом, что пул подключений существует независимо от существования объектов SqlConnection - на самом деле в его конструкторе идет сначала обращение к пулу, а при удалении - помещение подключения в пул. заново подключение не будет создаватся
1
748 / 547 / 48
Регистрация: 17.06.2010
Сообщений: 1,039
Записей в блоге: 1
10.04.2014, 10:32  [ТС] 8
Проверил с использованием using. соединения как висели в спящем состоянии, так и висят. По производительности что мой вариант с синглтоном, что с использованием using примерно одинаков. Проблема использования соединения с базой в многопоточном приложении остается открытой
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.04.2014, 10:32

Помощь в написании контрольных, курсовых и дипломных работ здесь.

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

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

Многопоточная работа программы
К сожалению, не могу сам разобраться с многопоточкой, перепробовал множество путей - отсебятина,...

Многопоточная работа с БД, отправка данных, обновление. Есть ли готовые решения?
Поток &quot;1&quot; читает данные, другие потоки берут из потока &quot;1&quot; и что-то делают. Если по какой-то...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.