2017-08-12 30 views
0

這是一個示例函數,它從連接池中獲取數據庫的連接並執行查詢並處理返回的結果。推遲:長時間運行功能的使用情況?

func dbQuery() error { 
    con := db.getConn() 
    result, err := con.Query() 
    if err != nil { 
     return err 
    } 
    defer con.close() // or con.close() 
    // Processing the result takes a long time 


    return nil 
} 

處理結果在這種情況下需要很長的時間和關閉不叫的連接,這意味着它不返回到連接池。
在這種情況下直接調用con.close(),當我們知道資源持續很長時間,即使它們不需要時,可以直接調用它嗎?

回答

2

在大多數情況下,Close()方法是冪等的,可以安全地調用一次以上。您在發生錯誤和/或早期函數返回的情況下可以使用defer con.Close(),但您完全可以在完成後立即致電Close()。所以是的,當你有一些長時間的功能時,最好使用這兩種方法。

+0

會是有意義的有這樣一個return語句返回'con.Close()'時可能被關閉返回一個錯誤()? 推遲con.Close()不允許任何錯誤處理權。 –

+0

@AnkitDeshpande好吧,從你的問題來看,我認爲你會在長功能完成之前的某個時間完成連接,此時你想關閉連接並將其釋放到池中。考慮到這個假設,在繼續使用函數之前,您是不是隻需捕獲err並像正常那樣測試它,並且只在實際存在錯誤時才返回? – RayfenWindspear

+0

@AnkitDeshpande:你*可以*通過使用命名返回參數並在延遲函數中設置它們來從'defer'返回值。 –

4

我的建議是重構你的代碼。這樣一個defer關閉前連接你處理結果:

func dbQuery() error { 
    result, err := getResult() 
    if err != nil { 
     return err 
    } 
    // Processing the result takes a long time 

    return nil 
} 

func getResult() (*Rows, error) { 
    con := db.getConn() 
    defer con.close() // or con.close() 

    result, err := con.Query() 
    if err != nil { 
     return nil, err 
    } 

    return result, err 
} 
相關問題