3 回答
TA贡献1788条经验 获得超4个赞
DB 将尽最大努力进行检测,但如果没有运气,它可能无法检测到。最好尽快发布获得的东西。
send()
系统调用将等待 TCP 连接发送数据,但客户端不会收到任何内容。
没有正确释放资源,发生断电、网络问题或裸退出。TCP keepalive 机制将启动并尝试检测连接已死。
客户端暂停,没有收到任何数据,在这种情况下
send()
会阻塞。
因此,它可能会阻止
正常关闭集群。
如果将排他锁作为事务的一部分(例如
auto vacuum
在 postgresql 中),则推进事件视界。
可以缩短服务器 keepalive 配置以更早地检测到它。(例如,~2h 12m
根据工作负载,postgresql 中的默认值会很长)。
最大打开连接数可能有硬性限制,直到检测到,一些连接将成为僵尸(在那里,无法使用但会降低限制)。
TA贡献1893条经验 获得超10个赞
数据库会注意到连接已经死亡并采取适当的措施:例如,该连接上所有未提交的活动事务将被回滚,用户会话将被终止。
但是请注意,从数据库引擎的角度来看,这是一个“恢复”场景:它不能在客户端断开连接时就抛出;它必须采取明确的行动来保持一致的状态。
另一方面,当程序以“正常方式”(即,不是因为恐慌或log.Fatal()
)关闭时关闭属性真的没有那么难。由于sql.DB
实例通常是一个程序范围的全局变量,它甚至更简单:只需main()
像马特建议的那样尝试关闭它。
TA贡献1886条经验 获得超2个赞
如果您在任何函数中初始化连接,通常最好推迟调用以立即关闭,即
conn := sql.Connect() // for example defer conn.Close()
一旦封闭函数退出,这将关闭连接。
这在main
函数中使用时很方便,因为一旦程序退出,Close()
就会调用。
- 3 回答
- 0 关注
- 150 浏览
添加回答
举报