2013-11-14 3 views
8

sql.Open() возвращает переменную типа * sql.DBGo/Golang sql.DB повторное использование функций

У меня есть функция, которая вызывает 10 других функций, которые все должны сделать базы данных вызовов

Является ли более правильным/эффективным:

  • Отправить указатель * sql.DB для каждой функции или
  • Создать новый * sql.DB объект в каждой функции

Значение

func DoLotsOfThings() { 
    db, _ := sql.Open() 
    defer db.Close() 
    DoTask1(db) 
    DoTask2(db) 
} 

или

func DoLotsOfThings() { 
    DoTask1() 
    DoTask2() 
} 

func DoTask1() { 
    db, _ := sql.Open() 
    defer db.Close() 
} 

func DoTask1() { 
    db, _ := sql.Open() 
    defer db.Close() 
} 

Причина, почему я спрашиваю, потому что я в настоящее время отправку указателя на каждую функцию и мой водитель, кажется, ломается. Я использую http://code.google.com/p/odbc, что заставляет меня полагать, что каждая функция должна иметь свои собственные, и что я могу полагаться на внутренности драйвера.

РЕДАКТИРОВАТЬ

RE поломки водителя, это происходит только при высоких условиях движения. И это происходит только после того, как говорят, минут десять или около того. Это заставляет меня думать, что есть какая-то утечка памяти, из-за которой использование драйвера перестает работать. Однако я откладываю db.Close() для каждого экземпляра * sql.DB, поэтому я не знаю, что еще я могу сделать, чтобы решить эту проблему.

andybalholm говорит Пулы соединений обрабатывается внутри, который, кажется, чтобы быть точным, потому что только после того, как ломается я пытаюсь выполнить что-то, не тогда, когда я призываю sql.Open()

Если я оставить свой Go приложение работает , он не сможет выполнять какие-либо SQL-запросы, но если я попытаюсь запустить другие тесты Go, которые отдельно подключаются к MSSQL и запускают запросы, он работает.

+0

Если вы можете опубликовать воспроизводимый пример здесь https://code.google.com/p/odbc/issues/list, я постараюсь его исправить. – alex

ответ

6

Вам не нужно открывать соединения с базой данных повсеместно. Пакет database/sql делает соединение пулом внутри, открывая и закрывая соединения по мере необходимости, обеспечивая иллюзию единственного соединения, которое может использоваться одновременно.

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

+0

Итак, у меня должна быть одна ссылка на sql.Open и полученный * sql.DB. Кажется, вы правы в пуле, я получаю ошибки только при попытке выполнить запрос. Как ни странно, приложение my go перестает подключаться к MSSQL, но за его пределами я могу запускать тесты, которые могут подключаться, пока я не запускаю хранимые процедуры.Это очень странно. –

+0

Одна вещь, которую следует помнить при попытке отладки приложений базы данных/sql, заключается в том, что из-за пула соединений ошибки соединения часто не появляются, когда вы делаете sql.Open; они ждут, пока вы запустите первый запрос в соединении. – andybalholm

18

Объявите var db *sql.DB глобально, а затем повторно используйте его через свой код. Вот пример (упрощенно):

var db *sql.DB 

func DoLotsOfThings() { 
    DoTask1(db) 
    DoTask2(db) 
} 

func main() { 
    db, _ = sql.Open() # or whatever you use 
    defer db.Close() 
    DoLotsOfThings() 
} 

Декларирование *sql.DB глобально также имеет некоторые дополнительные преимущества, такие как SetMaxIdleConns (регулирование размера пула соединений) или preparing операторов SQL через приложение.

+0

Спасибо за эту заметку! – Anatoly

Смежные вопросы