Обработка открытия и закрытия базы данных в подпрограммах

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

Некоторые из них связаны с извлечением данных из базы данных mysql.

Чтобы запланировать эти действия с фиксированным интервалом, я использую gocron. Работает неплохо.

Для базы данных на данный момент я создаю экземпляр в начале основной программы и передаю его подпрограммам. Я использую https://github.com/jmoiron/sqlx для работы с БД.

Поток кода:

i- инициализировать ресурсы. Например, db = sql.Open; поместите БД в общую структуру для передачи всем подпрограммам

ii- scheduleActions с использованием gocron (передавайте ресурсы по мере необходимости)

iii- действия - это конкретная подпрограмма, которая выполняет задачу по мере необходимости, используя данный ресурс (например, для БД)

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

Затем, как и ожидалось, я получаю сообщение об ошибке недопустимого соединения. что-то вроде

[mysql] packets.go:33: unexpected EOF
[mysql] packets.go:130: write tcp 127.0.0.1:36191->127.0.0.1:3306: write: broken pipe
[mysql] connection.go:312: invalid connection

Чтобы обойти это, я сделал реализацию, чтобы получить соединение с БД в подпрограмме и закрыть с помощью defer db.close (). При этом я получаю ошибку, связанную со слишком большим количеством открытых подключений. Я проверил правильное закрытие строк, а также использование сканирования. И посмотрите, как выполняются рекомендации.

Я хотел бы понять, как работать с открытием и закрытием БД в моем случае.

Вопросы, требующие помощи по отладке («почему этот код не работает?») Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для его воспроизведения в самом вопросе.
Adrian 25.05.2018 15:29
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
1
290
1

Ответы 1

Вы можете использовать sync.Once, чтобы предотвратить это:

var conn *sql.DB // Set package-wide, but not exported
var once sync.Once

func GetConnection() *sql.DB {
    once.Do(func() {
        var err error
        if conn, err = sql.Open("postgres", "<credentials>"); err != nil {
            log.Panic(err)
        }
        conn.SetMaxOpenConns(20) // Sane default
        conn.SetMaxIdleConns(0)
        conn.SetConnMaxLifetime(time.Nanosecond)
    })
    return conn
}

Прочтите это: https://aaronoellis.com/articles/preventing-max-connection-errors-in-go

Спасибо Алиреза. Я попробую и дам знать, сработает ли это.

user1050134 25.05.2018 10:16

Другие вопросы по теме