在关闭Go中的应用程序之前是否需要关闭数据库连接?

时间:2015-12-09 09:37:00

标签: sql database go

在Go中,当使用SQL数据库时,是否需要在关闭应用程序之前关闭数据库(db.Close)? DB会自动检测到连接已经死亡吗?

4 个答案:

答案 0 :(得分:4)

DB会尽力检测,但没有运气,可能无法检测到。最好尽快发布所获得的内容。

send()系统调用将等待TCP连接发送数据,但客户端不会收到任何内容。

  1. 在没有正确释放资源的情况下发生电源故障,网络问题或裸露退出。 TCP keepalive机制将启动并尝试检测该连接是否已死。

  2. 客户端已暂停且未收到任何数据,在这种情况下send()将阻止。

  3. 因此,它可能会阻止

    1. 正常关闭群集。
    2. 如果它将独占锁作为事务的一部分(例如postgresql中的auto vacuum),则推进事件视界。
    3. 可以缩短服务器keepalive配置以便更早地检测它。 (例如,根据工作量,postgresql中的~2h 12m默认值会很长。

      最大开放连接可能存在硬限制,直到检测到,某些连接将是僵尸(存在,不可用但限制减少)。

答案 1 :(得分:1)

数据库将注意到连接已经死亡并采取适当的操作:例如,将回滚在该连接上活动的所有未提交的事务,并终止用户会话。

但请注意,从数据库引擎的角度来看,这是一个“恢复”场景:当客户端断开连接时,它不能只是抛出;它宁愿采取明确的行动来保持一致的状态。

另一方面,当程序失败时关闭属性“正常方式”(也就是说,不是因为恐慌或log.Fatal())真的不那么难。由于sql.DB实例通常是程序范围的全局变量,因此更简单:只需尝试在main()中将其关闭,就像Matt建议的那样。

答案 2 :(得分:0)

优良作法是释放所使用的任何资源。你正在使用什么数据库。

答案 3 :(得分:0)

如果您在任何功能中初始化连接,通常最好不要立即关闭呼叫,即

conn := sql.Connect() // for example
defer conn.Close()

一旦封闭功能退出,将关闭连接。

main函数中使用时很方便,因为一旦程序退出,就会调用Close()