2017-08-12 41 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 
}