在Go中,当使用SQL数据库时,是否需要在关闭应用程序之前关闭数据库(db.Close
)? DB会自动检测到连接已经死亡吗?
答案 0 :(得分:4)
DB会尽力检测,但没有运气,可能无法检测到。最好尽快发布所获得的内容。
send()
系统调用将等待TCP连接发送数据,但客户端不会收到任何内容。
在没有正确释放资源的情况下发生电源故障,网络问题或裸露退出。 TCP keepalive机制将启动并尝试检测该连接是否已死。
客户端已暂停且未收到任何数据,在这种情况下send()
将阻止。
因此,它可能会阻止
auto vacuum
),则推进事件视界。可以缩短服务器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()
。