为了账号安全,请及时绑定邮箱和手机立即绑定

我们需要在关闭应用程序之前关闭数据库连接吗?

我们需要在关闭应用程序之前关闭数据库连接吗?

Go
幕布斯7119047 2021-11-29 15:35:32
在 Go 中,使用 SQL 数据库时,是否需要db.Close在关闭应用程序之前关闭DB ( )?DB 会自动检测到连接已经死了吗?
查看完整描述

3 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

DB 将尽最大努力进行检测,但如果没有运气,它可能无法检测到。最好尽快发布获得的东西。

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

  1. 没有正确释放资源,发生断电、网络问题或裸退出。TCP keepalive 机制将启动并尝试检测连接已死。

  2. 客户端暂停,没有收到任何数据,在这种情况下send()会阻塞。

因此,它可能会阻止

  1. 正常关闭集群。

  2. 如果将排他锁作为事务的一部分(例如auto vacuum在 postgresql 中),则推进事件视界。

可以缩短服务器 keepalive 配置以更早地检测到它。(例如,~2h 12m根据工作负载,postgresql 中的默认值会很长)。

最大打开连接数可能有硬性限制,直到检测到,一些连接将成为僵尸(在那里,无法使用但会降低限制)。


查看完整回答
反对 回复 2021-11-29
?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

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

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

另一方面,当程序以“正常方式”(即,不是因为恐慌或log.Fatal())关闭时关闭属性真的没有那么难。由于sql.DB实例通常是一个程序范围的全局变量,它甚至更简单:只需main()像马特建议的那样尝试关闭它。


查看完整回答
反对 回复 2021-11-29
?
MM们

TA贡献1886条经验 获得超2个赞

如果您在任何函数中初始化连接,通常最好推迟调用以立即关闭,即

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

一旦封闭函数退出,这将关闭连接。

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


查看完整回答
反对 回复 2021-11-29
  • 3 回答
  • 0 关注
  • 150 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信