2013-11-14 34 views
8

sql.Open() trả về một biến kiểu * sql.DBGo/Golang sql.DB tái sử dụng trong các chức năng

Tôi có một chức năng mà các cuộc gọi 10 chức năng khác mà tất cả cần phải thực hiện cơ sở dữ liệu gọi

là nó chính xác hơn/hiệu quả để:

  • Gửi con trỏ * sql.DB đến từng chức năng, hoặc
  • Tạo một đối tượng * sql.DB mới trong mỗi chức năng

Nghĩa

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

hoặc

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

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

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

Lý do tại sao tôi hỏi là vì tôi hiện đang gửi con trỏ đến từng chức năng và tài xế của tôi dường như phá vỡ. Tôi đang sử dụng http://code.google.com/p/odbc, điều này khiến tôi tin rằng mỗi chức năng cần phải có riêng của mình và tôi có thể dựa vào nội bộ của người lái xe.

EDIT

RE lái xe vỡ, nó chỉ xảy ra trong các môi trường giao thông cao. Và nó chỉ xảy ra sau khi nói, mười phút hoặc lâu hơn. Điều này khiến tôi tin rằng có một số loại rò rỉ bộ nhớ làm cho việc sử dụng trình điều khiển ngừng hoạt động. Tuy nhiên tôi trì hoãn db.Close() cho mỗi cá thể của * sql.DB, vì vậy tôi không biết những gì khác tôi có thể làm để giải quyết vấn đề này.

andybalholm nói tổng hợp kết nối được xử lý trong nội bộ, mà có vẻ là chính xác, bởi vì nó chỉ phá vỡ sau khi tôi cố gắng để thực hiện một cái gì đó, không phải khi tôi gọi sql.Open()

Nếu tôi rời Go ứng dụng của tôi chạy , nó sẽ không thể thực hiện bất kỳ loại truy vấn SQL nào, nhưng nếu tôi cố gắng chạy các kiểm tra Go khác kết nối riêng với MSSQL và chạy các truy vấn, nó hoạt động.

+0

Nếu bạn có thể đăng một ví dụ tái sản xuất tại đây https://code.google.com/p/odbc/issues/list, tôi sẽ cố gắng khắc phục nó. – alex

Trả lời

6

Bạn không cần mở các kết nối cơ sở dữ liệu khắp nơi. Gói cơ sở dữ liệu/sql thực hiện kết nối tổng hợp nội bộ, mở và đóng các kết nối khi cần thiết, đồng thời cung cấp ảo tưởng về một kết nối có thể được sử dụng đồng thời.

Có thể bạn cần phải tìm nơi khác vì nguyên nhân gây hỏng xe. Một số chi tiết về điều đó sẽ giúp mọi người dễ dàng tìm ra những gì đang diễn ra.

+0

Vì vậy, tôi nên có một tham chiếu đến sql.Open và kết quả * sql.DB. Có vẻ như bạn đang đúng về việc tổng hợp, tôi chỉ gặp lỗi khi cố gắng thực hiện truy vấn. Oddly ứng dụng đi của tôi dừng lại có thể kết nối với MSSQL, nhưng bên ngoài của nó, tôi có thể chạy thử nghiệm có thể kết nối, miễn là tôi không chạy các thủ tục được lưu trữ.Đó là tất cả rất lạ. –

+0

Một điều cần nhớ khi cố gắng gỡ lỗi cơ sở dữ liệu/ứng dụng sql là, vì kết nối tổng hợp, lỗi kết nối thường không hiển thị khi bạn làm sql.Open; họ đợi cho đến khi bạn chạy truy vấn đầu tiên trên kết nối. – andybalholm

18

Khai báo một số var db *sql.DB trên toàn cầu và sau đó sử dụng lại nó trên mã của bạn. Dưới đây là một ví dụ (giản thể):

var db *sql.DB 

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

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

Tuyên bố *sql.DB toàn cầu cũng có một số lợi ích bổ sung như SetMaxIdleConns (điều chỉnh kích thước hồ bơi kết nối) hoặc preparing câu lệnh SQL trên ứng dụng của bạn.

+0

Cảm ơn bạn đã lưu ý! – Anatoly

Các vấn đề liên quan